socket.io library for golang, a realtime application framework.

go-socket.io

GoDoc Build Status Coverage 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 client library SDK for Ably realtime messaging service

Ably Go A Go client library for www.ably.io, the realtime messaging service. Installation ~ $ go get -u github.com/ably/ably-go/ably Feature support T

Dec 2, 2022
Go-notification - Realtime notification system with golang

Realtime notification system Used Apache kafka gRPC & PROTOBUF MongoDB restapi w

Aug 19, 2022
🐇 Easy to use socket lib for Golang
🐇  Easy to use socket lib for Golang

Hare Sockets ?? Hare is a user-friendly lib for sockets in Golang. You can send and listen to TCP connections with a few lines of code. Contents Insta

Dec 26, 2022
A realtime distributed messaging platform
A realtime distributed messaging platform

Source: https://github.com/nsqio/nsq Issues: https://github.com/nsqio/nsq/issues Mailing List: [email protected] IRC: #nsq on freenode Docs:

Dec 29, 2022
HARAQA - High Availability Routing And Queueing Application
HARAQA - High Availability Routing And Queueing Application

haraqa is designed to be a developer friendly, scalable message queue for data persistence and real-time data streaming between microservices. Haraqa provides high-throughput, low-latency, fault-tolerant pipelines for architectures of any size.

Nov 1, 2022
Inspr is an application mesh for simple, fast and secure development of distributed applications.
Inspr is an application mesh for simple, fast and secure development of distributed applications.

Inspr is an engine for running distributed applications, using multiple communication patterns such as pub sub and more, focused on type consistency a

Jun 10, 2022
A quick introduction to how Apache Kafka works and differs from other messaging systems using an example application.
A quick introduction to how Apache Kafka works and differs from other messaging systems using an example application.

Apache Kafka in 6 minutes A quick introduction to how Apache Kafka works and differs from other messaging systems using an example application. In thi

Oct 27, 2021
The Bhojpur MDM is a software-as-a-service product used as a Mobile Device Manager based on Bhojpur.NET Platform for application delivery.

Bhojpur MDM - Mobile Device Manager The Bhojpur MDM is a software-as-a-service product used as a Mobile Device Manager based on Bhojpur.NET Platform f

Dec 31, 2021
May 11, 2023
:notes: Minimalist websocket framework for Go
:notes: Minimalist websocket framework for Go

melody ?? Minimalist websocket framework for Go. Melody is websocket framework based on github.com/gorilla/websocket that abstracts away the tedious p

Dec 30, 2022
Govent is an event bus framework for DDD event source implement

Govent is an event bus framework for DDD event source implement. Govent can also solve the package circular dependency problem.

Jan 28, 2022
Kafka, Beanstalkd, Pulsar Pub/Sub framework

go-queue Kafka, Beanstalkd, Pulsar Pub/Sub framework.

Sep 17, 2022
CQRS & Event-Sourcing Framework for Go.

goes - Event-Sourcing Framework goes is a collection of interfaces, tools, and backend implementations that allow you to write event-sourced applicati

Dec 27, 2022
golang client library to Viessmann Vitotrol web service

Package go-vitotrol provides access to the Viessmann™ Vitotrol™ cloud API for controlling/monitoring boilers. See https://www.viessmann.com/app_vitoda

Nov 16, 2022
golang long polling library. Makes web pub-sub easy via HTTP long-poll server :smiley: :coffee: :computer:
golang long polling library.  Makes web pub-sub easy via HTTP long-poll server :smiley: :coffee: :computer:

golongpoll Golang long polling library. Makes web pub-sub easy via an HTTP long-poll server. New in v1.1 Deprecated CreateManager and CreateCustomMana

Jan 6, 2023
A user friendly RabbitMQ library written in Golang.

TurboCookedRabbit A user friendly RabbitMQ library written in Golang to help use streadway/amqp. Based on my work found at CookedRabbit. Work Recently

Jan 6, 2023
GTA(Go Task Async) is a lightweight reliable asynchronous task and transaction message library for Golang

GTA (Go Task Async) is a lightweight and reliable asynchronous task and transaction message library for by golang.

Jun 4, 2022
Transpiled version of the CCXT exchange library to Go (Golang)

CCXT Go Transpiled CCXT exchange library from their original JavaScript source to Go (Golang). Features support 100+ cryptocurrency exchanges with a u

Oct 1, 2022
It's client library written in Golang for interacting with Linkedin Cruise Control using its HTTP API.

go-cruise-control It's client library (written in Golang) for interacting with Linkedin Cruise Control using its HTTP API. Supported Cruise Control ve

Jan 10, 2022