问题描述
从一个工作 socket.io
例子(后端:Python / Flask,前端:socket.io.js v2.0.3)开始,我现在尝试使用Go建立客户端,但无法通过握手阶段。对于长篇帖子的道歉......(最后还添加了一个Python客户端,它在Go中实现我想实现的功能)
(以下工作):
后端:
<$ ():
print(客户端连接请求sid+请求.sid)
@ socketio.on('join',namespace ='/ endpoint')
def join(message):
print(从客户端接收到的服务器: + message)
print(客户刚加入了请求sid的房间+ request.sid)
join_room(request.sid)
前端:
namespace =' /端点';
var socket = io.connect(location.protocol +'//'+ document.domain +':'+ location.port + namespace);
var client_join_message =这是客户端;
socket.emit('join',client_join_message);
开发者工具:我注意到一些请求,直到浏览器和服务器选择使用websockets和交换框架:
http:// localhost:5000 / socket.io /?EIO = 3& transport = polling& t = LxcgetJ
http:// localhost:5000 / socket.io /?EIO = 3& transport = polling& t = Lxcgetf& sid = 025e105a5093467d994a891367380aa3
http:// localhost:5000 / socket.io/?EIO = 3& transport = polling& t = Lxcgeti& sid = 025e105a5093467d994a891367380aa3 $ b $ $ b http:// localhost:5000 / socket.io /?EIO = 3& transport = polling& t = Lxcgetw& sid = 025e105a5093467d994a891367380aa3
http:// localhost:5000 / socket.io /?EIO = 3& amp ; transport = polling& t = Lxcgetx& sid = 025e105a5093467d994a891367380aa3
服务器日志:
GET /socket.io/?EIO=3&transport=polling& amp; t = LxcgetJ HTTP / 1.1200 381 0.000322
客户端连接请求sid 025e105a5093467d994a891367380aa3
POST /socket.io/?EIO=3&transport=polling&t=Lxcgetf&sid=025e105a5093467d994a891367380aa3 HTTP /1.1200 219 0.000806
(6450)已接受('127.0.0.1',45034)
GET /socket.io/?EIO=3&transport=polling&t=Lxcgeti&sid=025e105a5093467d994a891367380aa3 HTTP / 1.1200 227 0.003941
POST /socket.io/?EIO=3&transport=polling&t=Lxcgetw&sid=025e105a5093467d994a891367380aa3 HTTP / 1.1200 219 0.001650
GET / socket。 io /?EIO = 3& transport = polling& t = Lxcgetx& sid = 025e105a5093467d994a891367380aa3 HTTP / 1.1200 215 0.000235
从客户端收到的服务器:这是客户端
客户端刚刚与请求sid 025e105a5093467d994a891367380aa3
Go,(不起作用):
代码来自例如:
包裹主
进口(
github.com/graarh/golang-socketio
github.com/graarh/golang-socketio/transport
记录
运行时
time
)
func main(){
runtime.GOMAXPROCS(runtime.NumCPU())
c,err:= gosocketio.Dial(
gosocketio.GetUrl(127.0.0.1,5000,false),
transport.GetDefaultWebsocketTransport())
if err!= nil {
log.Fatal(err)
}
err = c.On(gosocketio.OnDisconnection,func(h * gosocketio.Channel){
log.Fatal 断开)
})
if err!= nil {
log.Fatal(err)
}
err = c.On(gosocketio .OnConnection,func(h * gosocketio。 Channel){
log.Println(Connected)
})
if err!= nil {
log.Fatal(err)
}
time.Sleep(1 * time.Second)
}
Go代码输出:
已连接
服务器日志:
GET / socket.io/?EIO=3&transport=websocket HTTP / 1.1200 0 1.004291
我错过了什么?使用Go代码,我没有看到任何 sid
, transport = polling
...此外,只有一个用 [go] [socket.io]
标记了几个问题,这让我觉得我选择了错误的路径......我会很感激任何想法,想法这个。
@John Weldon
如下:
客户:
$ go run gotest5.go
2017/10/11 11:21:40已连接
2017/10/11 11:21:40结果
2017/10/11 11:21:40完成
服务器:
(4380)wsgi启动http://127.0.0.1:5000
(4380)已接受('127.0.0.1',38860)
127.0.0.1 - - [11 / Oct / 2017 11 :21:40]GET /socket.io/?EIO=3&transport=websocket HTTP / 1.1200 0 0.003100
请注意,服务器上的。('connect'...)和上的函数
。('join',.. 。)
没有产生日志。
Python客户端(它的工作原理):
from socketIO_client import SocketIO,BaseNamespace
$ b $ class ThisNamespace(BaseNamespace):
def on_connect(self):
print('[Connected]')
def on_reconnect(self):
print('[Reconnected]')
def on_disconnect(self):
print('[Disconnected]')
与SocketIO('127.0.0.1', 5000,ThisNamespace)作为socketIO:
this_namespace = socketIO.define(ThisNamespace,'/ endpoint')
客户端日志:
python3 test.py
[已连接]
[已断开]
[Disconnected]
服务器日志:
(6047)wsgi启动http://127.0.0.1:5000
(6047)已接受('127.0.0.1',38900)
127.0。 0.1 - - [11 / Oct / 2017 11:53:27]GET /socket.io/?t=1507712007314-0&transport=polling&EIO=3 HTTP / 1.1200 381 0.000859
(6047)已接受('127.0.0.1',38902)
客户端连接请求sid 919ed69264dd4e9f93e7af0294970dbd
客户端与request.sid断开连接919ed69264dd4e9f93e7af0294970dbd
127.0.0.1 - - [11 / Oct / 2017 11 :53:27]GET /socket.io/?sid=919ed69264dd4e9f93e7af0294970dbd&transport=websocket&EIO=3 HTTP / 1.1200 0 0.032171
根据上面的评论,我们发现websocket连接本身正在工作。我认为问题在这里 - socket.io
是很多年前开发的,当时大多数浏览器和中间服务器/代理/路由器都不支持本地WebSockets。所以它有一个特殊的检查和回退时间来升级和降级连接(例如longpolling)。如果你已经安装了连接,你可以开始工作而不需要与另一个协议进行特殊的密钥交换尝试开始使用连接并在应用程序级别逻辑中执行下一步( Join
等)。 是否有效?
我认为现在WS得到99%客户的支持。如果你不想放松一些客户端不会工作,你可以在项目中保留 sockets.io
。但有时你必须在WS中实现它的连接逻辑。
Starting with a working socket.io
example (back-end: Python/Flask, front-end: socket.io.js v2.0.3), I now try to set up a client with Go but can't even pass the handshake phase. Apologies for the long post... (At the end have also added a Python client which does what I want to implement in Go)
(The following work):
back-end:
@socketio.on('connect', namespace='/endpoint')
def connect():
print("Client connected with request sid "+request.sid)
@socketio.on('join', namespace='/endpoint')
def join(message):
print("Server received from client:" +message)
print("Client just joined room with request sid "+request.sid)
join_room(request.sid)
front-end:
namespace = '/endpoint';
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
var client_join_message = "This is a client";
socket.emit('join', client_join_message);
Developer tools: I notice a few requests until the browser and the server select to use websockets and exchange frames:
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=LxcgetJ
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=Lxcgetf&sid=025e105a5093467d994a891367380aa3
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=Lxcgeti&sid=025e105a5093467d994a891367380aa3
ws://localhost:5000/socket.io/?EIO=3&transport=websocket&sid=025e105a5093467d994a891367380aa3
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=Lxcgetw&sid=025e105a5093467d994a891367380aa3
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=Lxcgetx&sid=025e105a5093467d994a891367380aa3
Server logs:
"GET /socket.io/?EIO=3&transport=polling&t=LxcgetJ HTTP/1.1" 200 381 0.000322
Client connected with request sid 025e105a5093467d994a891367380aa3
"POST /socket.io/?EIO=3&transport=polling&t=Lxcgetf&sid=025e105a5093467d994a891367380aa3 HTTP/1.1" 200 219 0.000806
(6450) accepted ('127.0.0.1', 45034)
"GET /socket.io/?EIO=3&transport=polling&t=Lxcgeti&sid=025e105a5093467d994a891367380aa3 HTTP/1.1" 200 227 0.003941
"POST /socket.io/?EIO=3&transport=polling&t=Lxcgetw&sid=025e105a5093467d994a891367380aa3 HTTP/1.1" 200 219 0.001650
"GET /socket.io/?EIO=3&transport=polling&t=Lxcgetx&sid=025e105a5093467d994a891367380aa3 HTTP/1.1" 200 215 0.000235
Server received from client:This is a client
Client just joined room with request sid 025e105a5093467d994a891367380aa3
My try with Go, (doesn't work):
The code comes from this client example in github.com/graarh/golang-socketio:
package main
import (
"github.com/graarh/golang-socketio"
"github.com/graarh/golang-socketio/transport"
"log"
"runtime"
"time"
)
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
c, err := gosocketio.Dial(
gosocketio.GetUrl("127.0.0.1", 5000, false),
transport.GetDefaultWebsocketTransport())
if err != nil {
log.Fatal(err)
}
err = c.On(gosocketio.OnDisconnection, func(h *gosocketio.Channel) {
log.Fatal("Disconnected")
})
if err != nil {
log.Fatal(err)
}
err = c.On(gosocketio.OnConnection, func(h *gosocketio.Channel) {
log.Println("Connected")
})
if err != nil {
log.Fatal(err)
}
time.Sleep(1 * time.Second)
}
Go code output:
Connected
Server logs:
"GET /socket.io/?EIO=3&transport=websocket HTTP/1.1" 200 0 1.004291
Is there anything that I'm missing? With the Go code I don't see any sid
, transport=polling
... Also, there are only a few questions tagged with [go] [socket.io]
, which makes me think I've chosen the wrong path... I would be grateful for any thoughts, ideas on this.
@John Weldon
Your code produces the following:
Client:
$ go run gotest5.go
2017/10/11 11:21:40 Connected
2017/10/11 11:21:40 result ""
2017/10/11 11:21:40 Done
Server:
(4380) wsgi starting up on http://127.0.0.1:5000
(4380) accepted ('127.0.0.1', 38860)
127.0.0.1 - - [11/Oct/2017 11:21:40] "GET /socket.io/?EIO=3&transport=websocket HTTP/1.1" 200 0 0.003100
Notice that the server functions on.('connect'...)
and on.('join',...)
didn't produce logs.
Python client (it works):
from socketIO_client import SocketIO, BaseNamespace
class ThisNamespace(BaseNamespace):
def on_connect(self):
print('[Connected]')
def on_reconnect(self):
print('[Reconnected]')
def on_disconnect(self):
print('[Disconnected]')
with SocketIO('127.0.0.1', 5000, ThisNamespace) as socketIO:
this_namespace = socketIO.define(ThisNamespace, '/endpoint')
client logs:
python3 test.py
[Connected]
[Disconnected]
[Disconnected]
server logs:
(6047) wsgi starting up on http://127.0.0.1:5000
(6047) accepted ('127.0.0.1', 38900)
127.0.0.1 - - [11/Oct/2017 11:53:27] "GET /socket.io/?t=1507712007314-0&transport=polling&EIO=3 HTTP/1.1" 200 381 0.000859
(6047) accepted ('127.0.0.1', 38902)
Client connected with request sid 919ed69264dd4e9f93e7af0294970dbd
Client disconnected with request.sid 919ed69264dd4e9f93e7af0294970dbd
127.0.0.1 - - [11/Oct/2017 11:53:27] "GET /socket.io/?sid=919ed69264dd4e9f93e7af0294970dbd&transport=websocket&EIO=3 HTTP/1.1" 200 0 0.032171
According to commentws above, we've found websocket connection itself is working. I think problem is here - socket.io
was developed many years ago when native WebSockets were not well supported by majority of browsers and inermediate servers/proxies/routers. So it has a special checks and fallbacks when to upgrade and downgrade a connection (to longpolling for example). If you have already installed connection you may start working without special key exchanges with another protocol.
Try to start using connection and performing next steps at application level logics (Join
and so on). Is it working?
I think nowadays WS are supported well for 99% of clients. If you want not to loose chance some client will be not working you may keep sockets.io
in project. But sometimes you'll have to realize its connections logics in WS.
这篇关于使用Go的socket.io客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!