【问题标题】:Socket.io support for WSO2 API Manager Websocket?Socket.io 是否支持 WSO2 API Manager Websocket?
【发布时间】:2021-01-31 00:21:40
【问题描述】:

WSO2 APIM 管理器中的内置 WebSocket API 是否支持基于 socket.io/nodejs 的端点?

我有基于 socket.io 的 websocket 服务器(在 NodeJS 中)和 socket.io javascript 客户端,在两者之间我们使用 WSO2 API 管理器来验证 websocket 连接。但是 WSO2 无法连接后端服务器并且没有给出任何响应。 我使用 access_token 查询参数来传递 Bearer 令牌(来自 JavaScript 客户端),它似乎没有错误。但是 WSO2 不会将请求转发到端点。

同样适用于原生 WebSocket 服务器-客户端。

【问题讨论】:

  • 可能是由于标头不匹配。控制台有错误吗?

标签: websocket socket.io wso2-am


【解决方案1】:

我终于摆脱了这个问题。 是的,WSO2 APIM websocket 支持 socket.io js 库,这将是我自己查询的第一个答案。更多关于这一点,这里有一些发现。

问题的实际原因是 socket.io 库和 WSO2 APIM 使用的请求 URL 模式。 Socket.io JS 库使最终 URL 以 / 结尾(reference),WSO2 使用的查询分离逻辑不接受。

简单来说,这是可以接受的

ws://localhost:9099/livefeed/v1?EIO=4&transport=websocket

但不是这个,

ws://localhost:9099/livefeed/v1/?EIO=4&transport=websocket

解决方案:

在与 WSO2 团队进行了几次讨论后,很明显,在他们的最后实施更改是不可能的。 socket.io.js 文件中的小技巧对我有用。

行号 - 2535

改变了这个,

_this.opts.path = _this.opts.path.replace(/\/$/, "") + "/";

到这里,

if(typeof opts.noslash!== 'undefined' && opts.noslash== "true"){
    _this.opts.path = _this.opts.path.replace(/\/$/, "");
}else{
   _this.opts.path = _this.opts.path.replace(/\/$/, "") + "/";
}

并使用额外的参数创建套接字。

 var socket = io.connect("http://localhost:9099?access_token=90e8sf10-3s1w-495f-b20d-5a009f63193v", { transports: ['websocket', 'polling'], path: '/livefeed/v1', noslash: 'true' });

我知道这不是一个实际的解决方案,但它对我有用。

【讨论】:

    【解决方案2】:

    之前的答案是针对 socket.io JS 客户端的,这里是针对 socket.io python 客户端的相同 hack。

    从 /home/user/.local/lib/python3.6/site-packages/engineio 修改 client.py 文件

    行号515

    改变这个,

    return ('{scheme}://{netloc}/{path}/?{query}'
                        '{sep}transport={transport}&EIO=3').format(...
    

    到这里,

    return ('{scheme}://{netloc}/{path}?{query}'
                            '{sep}transport={transport}&EIO=3').format(...
    

    现在,我们可以使用条件参数,而不是直接修改实际流程。

    if self.noslash == 'true':
                return ('{scheme}://{netloc}/{path}?{query}'
                        '{sep}transport={transport}&EIO=3').format(...
    

    否则返回原始语句。

    noslash参数可以从python的engineio和socketio库的connect()函数中获取。

    def connect(self, url, headers={}, transports=None,
                    engineio_path='engine.io', noslash=None):
           self.noslash = noslash
    

    这是 python-socketio 的示例连接字符串

    sio.connect('http://localhost:9099', headers={'Authorization':'Bearer 90e8sf10-3s1w-495f-b20d-5a009f63193v'}, transports=['websocket'], socketio_path='/livefeed/v1', noslash='true')
    

    【讨论】:

      【解决方案3】:

      您可以将以下日志添加到 /repository/conf/log4j.properties 以进一步调试问题。 对于 APIM 3.x.x 可以根据 log4j2 进行更改并添加到 log4j2.properties

      log4j.logger.org.wso2.carbon.inbound.endpoint.protocol.websocket.InboundWebsocketSourceHandler=DEBUG log4j.logger.org.wso2.carbon.inbound.endpoint.protocol.websocket.InboundWebsocketResponseSender=DEBUG 
      log4j.logger.org.wso2.carbon.websocket.transport.WebSocketClientHandler=DEBUG 
      log4j.logger.org.wso2.carbon.websocket.transport.WebsocketTransportSender=DEBUG
      

      【讨论】:

      • 谢谢@ruks,现在我收到了这些错误消息。你能提出什么问题吗? 未找到端口的 InboundWebsocketSourceHandler 端点:9099 租户域:null。我已经定义了端点,如果没有 WSO2 或者我使用核心 Websocket 服务器,它可以正常工作。
      猜你喜欢
      • 2012-11-05
      • 1970-01-01
      • 1970-01-01
      • 2018-07-24
      • 2021-03-26
      • 2013-12-07
      • 2015-03-23
      • 2013-11-28
      • 1970-01-01
      相关资源
      最近更新 更多