go-socket.io is library an implementation of Socket.IO in Golang

go-socket.io

GoDoc Build Status Go Report Card

go-socket.io is library an implementation of Socket.IO in Golang, which is a realtime application framework.

Current this library supports 1.4 version of the Socket.IO client. It supports room, namespaces and broadcast at now.

Help wanted This project is looking for contributors to help fix bugs and implement new features. Please check Issue 192. All help is much appreciated.

Contents

Install

Install the package with:

go get github.com/googollee/go-socket.io

Import it with:

import "github.com/googollee/go-socket.io"

and use socketio as the package name inside the code.

Example

Please check more examples into folder in project for details. Examples

FAQ

It is some popular questions about this repository:

  • Is this library supported socket.io version 2?
    • No, but if you wanna you can help to do it. Join us in community chat Telegram
  • How to use go-socket.io with CORS?
  • What is minimal version Golang support for this library?
    • We required Go 1.9 or upper!
  • How to user?
    • Go-socket.io compatibility with Socket.IO 0.9.x, please use branch 0.9.x * or tag [email protected]

Community

Telegram chat: @go_socketio

Engineio

This project contains a sub-package called engineio. This used to be a separate package under https://github.com/googollee/go-engine.io.

It contains the engine.io analog implementation of the original node-package. https://github.com/socketio/engine.io It can be used without the socket.io-implementation. Please check the README.md in engineio/.

License

The 3-clause BSD License - see LICENSE for more details

Comments
  • Client doesn't work with Node.js socket.io server

    Client doesn't work with Node.js socket.io server

    Using the socket.io client example, run against the node.js socket.io server example doesn't work. It appears as :

    panic: invalid status: 400 Bad Request
    
    goroutine 1 [running]:
    runtime.panic(0x642720, 0xc21000a820)
            /usr/lib/go/src/pkg/runtime/panic.c:266 +0xb6
    main.main()
            /home/david/Development/gowork/src/socketclient.go:25 +0x74
    
    goroutine 4 [syscall]:
    runtime.goexit()
            /usr/lib/go/src/pkg/runtime/proc.c:1394
    
    goroutine 5 [runnable]:
    net/http.(*persistConn).readLoop(0xc21005b400)
            /usr/lib/go/src/pkg/net/http/transport.go:778 +0x68f
    created by net/http.(*Transport).dialConn
            /usr/lib/go/src/pkg/net/http/transport.go:528 +0x607
    
    goroutine 6 [select]:
    net/http.(*persistConn).writeLoop(0xc21005b400)
            /usr/lib/go/src/pkg/net/http/transport.go:791 +0x271
    created by net/http.(*Transport).dialConn
            /usr/lib/go/src/pkg/net/http/transport.go:529 +0x61e
    

    The server returns a 400 error with the response message 'transport:undefined'

    The equivalent node.js client seems to connect to the socket.io url with an additional transport param set to 'polling', and then goes through a protocol upgrade to websockets.

    Is a node server/ go client expected to work?

  • example in documentation  report

    example in documentation report "http: multiple response.WriteHeader calls" error when client connect from browser. And the client received "Error during WebSocket handshake Ask Unexpected response code: 403"

    Hi, guys, I tried your example in branch 1.4, i write a simplest web page to conncet the example main.go server, first i received cors error, after fix that , then the server print out some log "http: multiple response.WriteHeader calls" and the client also report the error : "Error during WebSocket handshake Ask Unexpected response code: 403", do someone see this problem before?

  • disconnection event has not emit

    disconnection event has not emit

    use the demo file main.go refresh the browser,the log is:

    2014/08/17 17:40:03 main.go:17: on connection
    2014/08/17 17:40:06 main.go:17: on connection
    2014/08/17 17:40:07 main.go:17: on connection
    2014/08/17 17:40:09 main.go:17: on connection
    
  • http: response.WriteHeader on hijacked connection using websocket transport

    http: response.WriteHeader on hijacked connection using websocket transport

    Hi! Thanks for a library. I have faced a strange problem using it and cannot fix it by myself

    Here is a simple reproduce case:

    package main
    
    import (
        "log"
        "net/http"
    
        "github.com/googollee/go-socket.io"
    )
    
    func main() {
        server, err := socketio.NewServer(nil)
        if err != nil {
            log.Fatal(err)
        }
        server.On("connection", func(so socketio.Socket) {
            log.Println("on connection")
            so.Join("chat")
            so.On("chat message", func(msg string) {
                log.Println("emit:", so.Emit("chat message", msg))
                so.BroadcastTo("chat", "chat message", msg)
            })
            so.On("disconnection", func() {
                log.Println("on disconnect")
            })
        })
        server.On("error", func(so socketio.Socket, err error) {
            log.Println("error:", err)
        })
    
        http.Handle("/socket.io/", server)
        http.Handle("/", http.FileServer(http.Dir("./asset")))
        log.Println("Serving at localhost:5000...")
        log.Fatal(http.ListenAndServe(":5000", nil))
    }
    

    and in the browser I use something like

    <!doctype html>
    <html>
    <head>
        <title>Socket.IO chat</title>
    </head>
    <body>
    <script src="socket.io.js"></script>
    <script>
        var socket = io('localhost:5000', {transports: ["websocket"]})
        console.log(socket)
    </script>
    </body>
    </html>
    

    Then I see strange warnings in my applications's log:

    2015/11/21 20:43:30 Serving at localhost:5000...
    2015/11/21 20:43:35 http: response.WriteHeader on hijacked connection
    2015/11/21 20:43:35 on connection
    

    Using gdb I have found that the problem is that we are still serving http on hijacked connection.

    2015/11/21 20:46:17 Serving at localhost:5000...
    
    Breakpoint 1, net/http.(*response).WriteHeader (w=0xc8200b3810, code=400) at /usr/lib/go/src/net/http/server.go:683
    683         w.conn.server.logf("http: response.WriteHeader on hijacked connection")
    (gdb) bt
    #0  net/http.(*response).WriteHeader (w=0xc8200b3810, code=400) at /usr/lib/go/src/net/http/server.go:683
    #1  0x000000000065db00 in github.com/googollee/go-engine.io/websocket.(*Server).ServeHTTP (s=0xc82000e960, w=..., 
        r=0xc8200d2000) at /root/gopath/src/github.com/googollee/go-engine.io/websocket/server.go:35
    #2  0x00000000005d8cb9 in github.com/googollee/go-engine%2eio.(*serverConn).ServeHTTP (c=0xc820057d40, w=..., r=0xc8200d2000)
        at /root/gopath/src/github.com/googollee/go-engine.io/server_conn.go:197
    #3  0x00000000005d717d in github.com/googollee/go-engine%2eio.(*Server).ServeHTTP (s=0xc8200160e0, w=..., r=0xc8200d2000)
        at /root/gopath/src/github.com/googollee/go-engine.io/server.go:159
    #4  0x00000000004a5783 in github.com/googollee/go-socket%2eio.(*Server).ServeHTTP (s=0xc82000e660, w=..., r=0xc8200d2000)
        at /root/gopath/src/github.com/googollee/go-socket.io/server.go:87
    #5  0x000000000047d16d in net/http.(*ServeMux).ServeHTTP (mux=0xc820010960, w=..., r=0xc8200d2000)
        at /usr/lib/go/src/net/http/server.go:1699
    #6  0x000000000047dbde in net/http.serverHandler.ServeHTTP (sh=..., rw=..., req=0xc8200d2000)
        at /usr/lib/go/src/net/http/server.go:1862
    #7  0x000000000047b3ce in net/http.(*conn).serve (c=0xc8200b3550) at /usr/lib/go/src/net/http/server.go:1361
    #8  0x000000000045bd01 in runtime.goexit () at /usr/lib/go/src/runtime/asm_amd64.s:1696
    #9  0x000000c8200b3550 in ?? ()
    #10 0x0000000000000000 in ?? ()
    

    But I am not familiar with websockets and your implementation to go further.

    Is it my mistake somewhere or bug in library? Thank you

  • I'm getting bad request

    I'm getting bad request

    When emitting events from client, I got Bad Request

    POST http://localhost:8500/socket.io/?EIO=3&transport=polling&t=1578039627529-2&sid=4 400 (Bad Request)

    And on the server console, it said 'resume'

    Here's my client code:

    var socket = io();
    
    var mesageForm = document.getElementById('send-container');
    var mesageContainer = document.getElementById('message-container');
    var mesageInput = document.getElementById('message-input');
    
    
    const name = prompt('What is your name?');
    appendMessage('You' + ' joined');
    
    socket.emit('new-user', name);
    
    socket.on('chat-message', data => {
        appendMessage(data)
    });
    
    socket.on('user-connected', name => {
        appendMessage(name + ' joined')
    });
    
    mesageForm.addEventListener('submit', function (e) {
        e.preventDefault();
    
        const message = mesageInput.value;
        socket.emit('send-chat-message', message);
        mesageInput.value = ''
    });
    
    function appendMessage(msg) {
        const messageElement = document.createElement('div');
    
        messageElement.innerText = msg;
        mesageContainer.append(messageElement)
    }
    

    And here's my server code

    package main
    
    import (
    	socketio "github.com/googollee/go-socket.io"
    	"github.com/labstack/echo"
    )
    
    type Sock struct {
    	sock socketio.Conn
    	Name string
    }
    
    var socks = make(map[string]Sock)
    
    func main() {
    	io, _ := socketio.NewServer(nil)
    	
    	app := echo.New()
    	
    	app.Static("/", ".")
    	
    	app.Any("/socket.io/", func(s echo.Context) error {
    		io.ServeHTTP(s.Response().Writer, s.Request())
    		
    		return nil
    	})
    	
    	io.OnConnect("/", func(s socketio.Conn) error {
    		socks[s.ID()] = Sock{
    			sock: s,
    		}
    		
    		s.Emit("chat-message", "Server: Hello World")
    		
    		return nil
    	})
    	
    	io.OnEvent("/", "new-user", func(s socketio.Conn, name string) {
    		sk := socks[s.ID()]
    		sk.Name = name
    		
    		for k, v := range socks {
    			if k != s.ID() {
    				v.sock.Emit("user-connected", name)
    			}
    		}
    	})
    	
    	io.OnEvent("/", "send-chat-message", func(s socketio.Conn, msg string) {
    		for k, v := range socks {
    			if k != s.ID() {
    				v.sock.Emit("chat-message", msg)
    			}
    		}
    	})
    	
    	go io.Serve()
    	defer io.Close()
    	
    	app.Start(":8500")
    }
    

    It's annoying. What is causing this error?

  • I getting unexpected and unexplained message while running the socket

    I getting unexpected and unexplained message while running the socket

    Describe the bug I'm getting the bellow message and not sure why its coming and how to solve it "Did you forget to Close() the ReadCloser from NextReader?"

    To Reproduce Run a socket connection with multiple clients which keep sending message

    Expected behavior should explain where this problem is happening and logs or point towards how to solve it

    Environment (please complete the following information):

    • Go version: 1.13
    • Server version v1.4.3
    • Client version v2.3.0

    Additional context "Did you forget to Close() the ReadCloser from NextReader?"

  • Namespace isn't working

    Namespace isn't working

    My namespace isn't working with this code, someone knows why?

    //Server 
        server, err := socketio.NewServer(nil)
        if err != nil {
            log.Fatal(err)
        }
    
        profile := server.Of("/profile")
    
        profile.On("connection", func(so socketio.Socket) {
            log.Print("Connect NSP:PROFILE")
        })
    
        server.On("connection", func(so socketio.Socket) {
            log.Print("CONNECT DEFAULT")
        })
    
    //Client
    <script>
        console.log("Err:")
        var socket = io("http://localhost:5000");
        socket.on('news', function (data) {
            console.log(data);
            socket.emit('my other event', { my: 'data' });
        });
    
        var socket2 = io("http://localhost:5000/profile");
        socket2.on('connect', function() {
            socket2.emit('authorization', "user1");
        })
    </script>
    

    OUTPUT:

    2016/07/26 17:32:44 CONNECT DEFAULT 2016/07/26 17:32:44 CONNECT DEFAULT

  • Events emitted from server not heard by client

    Events emitted from server not heard by client

    Hi, first thank you for this project.

    I am working on simple demo to stream some data to the client. I am running into an issue where I am not hearing events which are emitted from server on the client. Here is what my use case looks like:

    Server:

    server.On("connection", func(so socketio.Socket) {
       log.Println("user connected")
    
       go tweets()
    
       so.On("get-tweets-data", func() {
           log.Println("I heard event from client!")
           so.Emit("tweets-data")
       })
       so.On("disconnection", func() {
           log.Println("user disconnected")
       })
    })
    

    Client:

    socket.on('connect', function(data) {
    
      socket.emit('get-tweets-data');
    
      socket.on('tweets-data', function(data) {
        console.log('received data from the server');
      });
    
    });
    

    I heard the initial "get-tweets-data" call from the client, but after that when I try to callback to the client from server something gets lost in translation.

    If I move the Emit outside of the On event, it works fine.

    server.On("connection", func(so socketio.Socket) {
       log.Println("user connected")
    
       go tweets()
    
       so.On("get-tweets-data", func() {
           log.Println("I heard event from client!")
       })
       so.On("disconnection", func() {
           log.Println("user disconnected")
       })
       so.Emit("tweets-data")
    })
    
  • Did you forget to Close() the ReadCloser from NextReader?

    Did you forget to Close() the ReadCloser from NextReader?

    What is this log on the server-side? And what will happen if we emit to a conn that has closed?

    Did you forget to Close() the ReadCloser from NextReader?

  • Remove/merge go-engine.io into go-socket.io.

    Remove/merge go-engine.io into go-socket.io.

    Background

    I don't think anyone will use go-engine.io without go-socket.io. Separating these 2 projects will make the dependency complex and hard to do static analysis.

    Content

    Drop go-engine.io. go-socket.io should contain all features of go-engine.io. We could put these features in connection subdirectory because go-engine.io maintains a connection. engine is not a good name here.

  • Performance

    Performance

    Hi. I'm a beginner in Golang and wrote a server application with this library. My problem is that when just one user connects to the server with socket, the CPU performance of the server is going upper than 100%. Do you have any idea? I registered about 35 events on the server socket. Also when I send an event from the client to the server, It’s taking a too long time to call event on the server. The server state and ping time is OK.

  • Not working OnEvent Method with return string

    Not working OnEvent Method with return string

    Describe the bug Expect similar behaviour for double methods: OnEvent with Emit and OnEvent with return string

    To Reproduce use simple example from https://github.com/socketio/chat-example

    server.OnEvent("/", "chat message", func(s socketio.Conn, msg string) {
    	s.Emit("chat message", "have: "+msg)
    })
    
    server.OnEvent("/", "chat message", func(s socketio.Conn, msg string) string {
    	return "recv " + msg
    })
    
    client accept message by websocket, but it doesn't output by ui. maybe problem into socketio js. client 
    

    Expected behavior server in event with return must be working.

    Environment (please complete the following information):

    • Go version: [v1.19]
    • Server version [master - 913e8c2d7c6898e2c2084c187d82da37e13f281f]
    • Client version [v1.7.4]

    Additional context Add any other context about the problem here.

  • How to use go-engine.io or go-socket.io as the client?

    How to use go-engine.io or go-socket.io as the client?

    I checked the previous issue and found that go-engine.io was used as the client, but an error was reported

    the error is unsupported protocol scheme "wss"

    The version of socket. io used by the server is 1.7.4, and the nodejs socket client can be used to connect normally, but it cannot be connected using golang

    image

  • Frequent hangs

    Frequent hangs

    I have a private project which uses go-socket.io. Frequently, all connections will hang when connecting, for around a second, as shown by gin debug logs: image

    Only a few packets go through before the problem: image (at this point, server.OnConnect() is not yet triggered.)

    According to pprof, most of the time is spent on payload.Working(): screen

    This can be really annoying for the users.

  • Socket error

    Socket error

    When connecting from socketio client.. its throwing error

    Error: server error at Socket.onPacket (socket.js?0112:317:1) at Emitter.emit (index.js?5641:143:1) at XHR.onPacket (transport.js?1272:100:1) at callback (polling.js?ae7b:83:1) at Array.forEach () at XHR.onData (polling.js?ae7b:86:1) at Emitter.emit (index.js?5641:143:1) at Request.onData (polling-xhr.js?cb5e:188:1) at Request.onLoad (polling-xhr.js?cb5e:229:1) at xhr.onreadystatechange (polling-xhr.js?cb5e:147:1)

    How can I log the incoming connections and any other events to server.

  • Bad Request with payload paused

    Bad Request with payload paused

    go version: 1.19 go-socket.oi version: 1.6.2 socket-io js client version: 1.7.4

    request header image

    request payload image

    response image

    Before submit this issue, i had quick read go-socket.io source code, and found out the errPaused, it shoud be retryError, and ignored to response, image

    I'm not very sure what i had done lead to this situation

    And follow my server side code:

    // gin request entry
    func StartSocketIO(ctx *gin.Context) {
    	GetServ().ServeHTTP(ctx.Writer, ctx.Request)
    }
    
    // init socket server
    func initSocketIOServer() *socketio.Server {
    	s := socketio.NewServer(&engineio.Options{
    		Transports: []transport.Transport{
    			&polling.Transport{
    				CheckOrigin: allowOrigin,
    			},
    			&websocket.Transport{
    				ReadBufferSize:  1024,
    				WriteBufferSize: 1024,
    				CheckOrigin:     allowOrigin,
    			},
    		},
    	})
    	s.OnConnect(NspRoot, func(c socketio.Conn) error {
    		logger.GetLogger().Info("connected root:", c.ID())
    		return nil
    	})
    	s.OnConnect(NspVulBox, func(c socketio.Conn) error {
    		logger.GetLogger().Info("connected socket.io/vulbox:", c.ID())
    		clientsCount++
    		c.SetContext(NewContext())
    		c.Join(RoomUnsigned)
    		return nil
    	})
    	s.OnError(NspVulBox, func(c socketio.Conn, e error) {
    		logger.GetLogger().Error("error: ", e)
    	})
    	s.OnDisconnect(NspVulBox, func(c socketio.Conn, reason string) {
    		logger.GetLogger().Info("closed: ", reason)
    		if user, ok := c.Context().(*SettableContext).Get(UserInContext); ok {
    			removeUserClient(*user.(*middleware.VulBoxClaims), c)
    		}
    	})
    	return s
    }
    

    client code:

    $(function() {
      var socket = io("https://localhost:8080/", {path: "/socket.io/"});
    
      // Socket events
      socket.on('connect', function (data) {
        socket.emit('Authorization', "Bearer with authorize code");
        socket.emit('Message', {"msg": "hello connection"})
      })
    
      socket.on('logged', function (data) {
        console.log(data)
        socket.emit('Message', {"msg": 'hello'})
      })
    
      socket.on('Message', function (data) {
        console.log(data)
      })
    
      socket.on('disconnect', function () {
        console.log('you have been disconnected');
      });
    
      socket.on('reconnect', function () {
        console.log('you have been reconnected');
      });
    
      socket.on('reconnect_error', function () {
        console.log('attempt to reconnect has failed');
      });
    });
    

    Any advice is welcome, thanks all again.

Go socket with SO_REUSEPORT and SO_REUSEADDR flags
Go socket with SO_REUSEPORT and SO_REUSEADDR flags

This library helps go developers to open sockets with SO_REUSEPORT and SO_REUSEADDR flags. Why ? This flags will allow many processes to bind to the s

Dec 29, 2022
A fast, well-tested and widely used WebSocket implementation for Go.

Gorilla WebSocket Gorilla WebSocket is a Go implementation of the WebSocket protocol. Documentation API Reference Chat example Command example Client

Jan 2, 2023
BrisGolang is a Go implementation of the game of briscola using the WebSocket protocol for client/server communication.

BrisGolang BrisGolang is a Go implementation of the game of briscola using the WebSocket protocol for client/server communication. Usage You can play

Nov 1, 2021
Client Implementation of eosio state-history websocket.

Client Implementation of eosio state-history websocket.

Dec 6, 2022
Tiny WebSocket library for Go.

RFC6455 WebSocket implementation in Go.

Dec 28, 2022
Minimal and idiomatic WebSocket library for Go

websocket websocket is a minimal and idiomatic WebSocket library for Go. Install go get nhooyr.io/websocket Highlights Minimal and idiomatic API First

Dec 31, 2022
Real-time messaging library for Go with scalability in mind.

This library has no v1 release, API still evolves. Use with strict versioning. Before v1 release patch version updates only have backwards compatible

Dec 31, 2022
A go library for consuming Binance Websocket Market Streams

binancestream A go library for consuming Binance Websocket Market Streams This library handles network failures by automatically reconnecting to the w

Aug 1, 2022
A websocket powered discord wrapper for Sugaroid written in golang

sg-discord A thin discord wrapper built on top of Sugaroid Websocket implementation. Build go build . Run export DISCORD_BOT_TOKEN="supersecrettoken"

Dec 30, 2021
A websocket powered telegram wrapper for Sugaroid written in golang

sg-telegram A thin telegram wrapper built on top of Sugaroid Websocket

Nov 4, 2021
Simle websocket chat on Golang

WebsocketChat Simle websocket chat on Golang Installation (with comiling binary files): cd projectDir/cmd/app/server - change current directory go bui

Nov 1, 2021
🚀 BiliBili Live WebSocket Protocol SDK in Golang
🚀 BiliBili Live WebSocket Protocol SDK in Golang

BiliGO-LIVE BiliBili Live WebSocket Protocol SDK in Golang 简介 v0版本不保证对外函数、结构的不变性,请勿大规模用于生产环境 哔哩哔哩直播 WebSocket 协议的 Golang 封装 特性 良好的设计,自定义程度高 代码、结构体注释完善

Oct 30, 2022
Websockets - Chaotic Web Sockets With Golang

Chaotic Web Sockets The intention of this project is to show the behavior of a s

Jan 21, 2022
Encrypted-websocket-chat - Encrypted websocket chat using golang

Encrypted websocket chat First version written in python This version should be

Sep 15, 2022
Glue - Robust Go and Javascript Socket Library (Alternative to Socket.io)

Glue - Robust Go and Javascript Socket Library Glue is a real-time bidirectional socket library. It is a clean, robust and efficient alternative to so

Nov 25, 2022
Glue - Robust Go and Javascript Socket Library (Alternative to Socket.io)

Glue - Robust Go and Javascript Socket Library Glue is a real-time bidirectional socket library. It is a clean, robust and efficient alternative to so

Nov 25, 2022
GOWS is GoLang web-socket module Provides you with ease of handling web socket connections with a few lines

GOWS GOWS is GoLang web-socket module Provides you with ease of handling web socket connections with a few lines, it supports multi-connection on one

Apr 4, 2022
Simple Relay between a Unix socket and a TCP socket, and vice versa.
Simple Relay between a Unix socket and a TCP socket, and vice versa.

Simple TCP <-> Unix Relay simpletcpunixrelay is a program which exposes a TCP endpoint as a Unix socket and vice versa. Usecase Let's say you are runn

Nov 23, 2022
A diffie-hellman socket implementation in golang.

I tried to implement the diffie hellman key exchange in golang with the use of sockets to understand how this protocol works and to learn golang. So its a development project: obviously don't use it in production.

Aug 9, 2022
A Socket.IO backend implementation written in Go

go-socket.io The socketio package is a simple abstraction layer for different web browser- supported transport mechanisms. It is fully compatible with

Sep 25, 2022