我在WebSocket上遇到了一个奇怪的问题。当我打开一个新的套接字时,我让服务器和客户端互相发送握手消息。然而,代码似乎只是偶尔执行。
服务器代码(ruby):
# Set up the websocket server on port 8080
EventMachine::WebSocket.start(:host => "localhost", :port => 8080, :secure => false) do |ws|
ws.onopen do
ws.send "WebSocket opened on port 8080."
end
ws.onmessage do |msg|
puts msg
end
ws.onclose do
puts "WebSocket closed."
end
end
客户端代码(javascript):
connection.onopen = function() {
connection.send("Ping!");
};
connection.onerror = function() {
console.log("WebSocket error.");
};
connection.onmessage = function(e) {
console.log("Server: " + e.data);
};
服务器端的控制台输出经过一些刷新,每次等待几秒钟:
WebSocket closed.
WebSocket closed.
WebSocket closed.
Ping!
WebSocket closed.
WebSocket closed.
WebSocket closed.
WebSocket closed.
Ping!
WebSocket closed.
WebSocket closed.
每次发布"Ping!"时,客户端也会收到指向它的握手消息。因此,失败在双方——当它起作用时,双方都会收到自己的消息。
这可能是什么原因造成的?
这可能是EventMachine::WebSocket
的问题吗?
我想知道是否所有的连接闭包都是websocket连接。也许你的浏览器也在尝试使用Http访问页面?
是否可能在Websocket对"Ping"的响应可用之前关闭了连接?
您可以尝试使用其他服务器端解决方案来检查是否存在此问题。
例如,您可以使用Plezi来测试客户端并收集更多信息。即(在irb
中):
require 'plezi'
class TestController
def index
puts "Got HTTP request"
"Hello World"
end
def on_open
puts "Websocket Opened."
write "Websocket Opened."
end
def on_message data
puts "Got: #{data}"
write "pong"
end
def on_close
puts "Websocket Closed."
end
end
route '/', TestController
# if using `irb`, use:
exit # to start server
祝你好运。
附言:默认端口为3000。
如果你想,你可以使用:
Plezi.port = 8080
或者运行带有-p
参数的脚本(如果不使用irb
,则省略exit
指令):
$ ruby ./server.rb -p 8080
如何调用Javascript?是否有一些依赖项需要先加载?连接定义在哪里?
这可能是一个竞赛条件吗?假设js-WebSocket在构建时连接,那么在onopen
事件被触发并发送(没有任何效果)到未定义的处理程序之前,您可能无法添加该事件处理程序?