使用Go的socket.io客户端 [英] socket.io client using Go

查看:1899
本文介绍了使用Go的socket.io客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从一个工作 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,(不起作用):






代码来自 client 例如 github.com/graarh/golang-socketio

 包裹主

进口(
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客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆