是否可以获取传入 websocket 连接的 IP 地址?
Posted
技术标签:
【中文标题】是否可以获取传入 websocket 连接的 IP 地址?【英文标题】:Is it possible to get the IP address of an incoming websocket connection? 【发布时间】:2018-10-23 13:31:09 【问题描述】:我的 websocket 服务器是这样运行的:
ws_hdl = WebSocketHandler.new do |ws|
# here we should determine the IP address of an incoming connection
end
srv = Server.new ws_hdl
srv.listen("0.0.0.0", 8080)
是否可以获取远程主机的IP地址? 它是日志记录和安全原因所必需的。
提前感谢任何好的建议!
【问题讨论】:
【参考方案1】:我不知道你用的是什么,但Kemal 我会这样做:
require "kemal"
ws "/" do |socket, env|
p env.request
end
Kemal.run
标题如下所示:
HTTP::Headers"Host" => "example.com:80", "User-Agent" => “curl/7.49.1”、“接受”=>“/”、“连接”=>“升级”、“升级” => "websocket", "Origin" => "http://example.com:80", "Sec-WebSocket-Key" => "SGVsbG8sIHdvcmxkIQ==", "Sec-WebSocket-Version" => "13"
然后需要在客户端前面设置像 nginx 这样的代理来添加 IP 到 headers:https://***.com/a/27458651/1597964
【讨论】:
我只使用标准的 Crystal API 来保持 websocket 连接。不要认为将 Kemal 用于可以使用标准 API 解决的任务是一个好主意。感谢您使用 Nginx 添加附加标头的想法!【参考方案2】:抱歉,我无法正确测试,但我想我有一个解决方案。
该块具有网络套接字ws
,但也可以具有HTTP::Context 作为第二个参数。这将包含一个HTTP::Request,其中包含标题。包括像REMOTE_ADDR
这样的东西。
ws_hdl = WebSocketHandler.new do |ws, context|
context.request.headers # all headers
context.request.headers["REMOTE_ADDR"]? # Should be the IP address
end
srv = Server.new ws_hdl
srv.listen("0.0.0.0", 8080)
【讨论】:
不!有关远程主机的信息不通过 HTTP 标头传输! Web 服务器可以自行确定远程客户端地址并将其提供给服务器的 API。但不幸的是,Crystal 的内置 Web 服务器不提供此信息。因此,目前记录远程客户端 IP 的唯一方法是通过 nginx 服务器代理连接并在请求中添加额外的标头。估计是Crystal的web server api的一个很大的毛病!以上是关于是否可以获取传入 websocket 连接的 IP 地址?的主要内容,如果未能解决你的问题,请参考以下文章
在 Angular 和 rxjs 中重新连接 websocket?