我在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!”发布后,客户端还会收到指向它的握手消息。所以双方都失败了 - 当它发挥作用时,双方都会收到他们的消息。
这可能是什么原因?
答案 0 :(得分:1)
这可能是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
祝你好运。
P.S。默认端口为3000。
如果需要,您可以使用:
Plezi.port = 8080
或者使用exit
参数运行您的脚本(如果不使用irb
,则省略-p
指令):
$ ruby ./server.rb -p 8080
答案 1 :(得分:0)
你是如何调用Javascript的?是否存在需要首先加载的依赖项?连接在哪里定义?
答案 2 :(得分:0)
这可能是竞争条件吗?鉴于js WebSocket在构造时连接,也许你不能在事件触发之前添加onopen
事件处理程序,并且发送(没有任何影响)到未定义的处理程序?