Git Product home page Git Product logo

go-socket.io's Introduction

go-socket.io

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.

Badges

Build Status GoDoc License Release Go Report Card

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?

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

go-socket.io's People

Contributors

adrianmxb avatar annlumia avatar artushin avatar bguiz avatar chappjc avatar cyberlight avatar dependabot[bot] avatar dimagv avatar disruptivemind avatar erkie avatar evsamsonov avatar fujimoto avatar googollee avatar grahamjenson avatar hongruiqi avatar ipv4sec avatar m25n avatar mountkin avatar mtsgrd avatar mweibel avatar nazri avatar nkovacs avatar orlovevgeny avatar ralfbawg avatar rykov avatar sshaplygin avatar steveoc64 avatar timstudd avatar togtja avatar withshubh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-socket.io's Issues

panic: reflect: Call with too few input arguments

With a socket.io server like this

server, _ := socketio.NewServer(nil)
server.On("error", func(so socketio.Socket, err error) {
    if so != nil {
        log.Printf("Error %s: %s", so.Id(), err.Error())
    } else {
        log.Printf("Error: %s", err.Error())
    }
})
server.On("connection", func(so socketio.Socket) {
    log.Printf("Connected")
    sockets.Set(so.Id(), so)
    so.On("disconnection", func() {
        log.Printf("Disconnected")
        sockets.Remove(so.Id())
    })
})

server.On("join", func(so socketio.Socket, roomName string) {
    log.Printf("Joining room %s", roomName)
})

And a javascript call like this

socket.emit("join");

We get the following error

panic: reflect: Call with too few input arguments

goroutine 33 [running]:
reflect.Value.call(0x2cfea0, 0x4595f0, 0x13, 0x397c70, 0x4, 0xc20801c800, 0x1, 0x1, 0x0, 0x0, ...)
    /usr/local/Cellar/go/1.4/libexec/src/reflect/value.go:352 +0x13f7
reflect.Value.Call(0x2cfea0, 0x4595f0, 0x13, 0xc20801c800, 0x1, 0x1, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4/libexec/src/reflect/value.go:296 +0xbc
github.com/googollee/go-socket%2eio.(*caller).Call(0xc208032400, 0x646a78, 0xc208128000, 0x586550, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/pivotal/workspace/go/src/github.com/googollee/go-socket.io/caller.go:75 +0x3e8
github.com/googollee/go-socket%2eio.(*socketHandler).onPacket(0xc20812c000, 0xc20809a280, 0xc20809a2c0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/pivotal/workspace/go/src/github.com/googollee/go-socket.io/handler.go:153 +0x2e8
github.com/googollee/go-socket%2eio.(*socket).loop(0xc208128000, 0x0, 0x0)
    /Users/pivotal/workspace/go/src/github.com/googollee/go-socket.io/socket.go:125 +0x37b
github.com/googollee/go-socket%2eio.func·003(0xc208128000)
    /Users/pivotal/workspace/go/src/github.com/googollee/go-socket.io/server.go:78 +0x28
created by github.com/googollee/go-socket%2eio.(*Server).loop
    /Users/pivotal/workspace/go/src/github.com/googollee/go-socket.io/server.go:79 +0x109

When we pass in a room name to the emit function, everything works properly. However, emitting without the room name causes the server to explode. It's fine for the server to disconnect or transmit an error. Crashing is a security risk and operations nightmare since anybody can bring down the server just by sending the wrong message over the wire.

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")
})

emit 二级map包含中文出错

m:=make(map[string]interface{})
m["a"]="你好"
e:=so.Emit("cn1111",m)
//正常 e==nil

b:=make(map[string]string)
b["u-a"]="中文内容" //换做英文正常
m["b-c"]=b
e=so.Emit("cn2222",m)
//异常 e==nil 会强制断开客户端 数据发送失败

Client API

Currently there is only the Server API. Are there any plans to add a client as well?

access origins issue

I am having issue connecting a client from localhost:3000 -> localhost:5000

The two apps have to be separate. How do I set the access-control header in this lib.

Error on go get

I'm new to the language so I apologize if I'm doing something wrong on my end, but I'm getting this error when running go get.

# github.com/googollee/go-socket.io
/usr/lib/go/src/pkg/github.com/googollee/go-socket.io/server.go:104: method transport.webSocketHandler is not an expression, must be called

What exactly is `BroadcastTo` supposed to do?

I think I may be misunderstanding, but it seems like BroadcastTo() should have the ability to target a very specific channel instead of a standard Emit() which seems to blast to all connected clients.

Take for example the following code, If I am incorrect in understanding the appropriate usage of BroadcastTo I would love some direction:

so.On("handshake", func(msg string) {
    so.Join(so.Id())
    so.BroadcastTo(so.Id(), "handshake", "Welcome! You have done a handshake!.")
})

From my understanding we have a client with sid of abc-123 who now joins the channel abc-123 and we immediately turn around and emit to only the channel abc-123. So only that client should see the message. Am I wrong?

0.9.x branch client single message sent received duplicate at Node.js 0.9.14 server

When i'm using the go socket io client from the 0.9.x (branch/tag/whatever) against the node.js socket io v0.9.14 i'm receiving duplicate messages at the server side. Has anybody seen this or know what I'm doing wrong or whether there might be a bug along the way (socket->codec->websocketFrameWriter->hybi->socket) If it's relevant at all, I don't have the option to use socket io 1.+. so there's that as well.

edit: apologies for bad formatting.

Using this client code on the go side:
client, err := socketio.Dial("http://127.0.0.1:8088")
if err != nil {
fmt.Println(err)
return
}

client.On("connect", func(ns *socketio.NameSpace) {
    fmt.Println("connected to socket!")
    ns.Emit("message", "here is a test message")
})

client.Run()

And this code at the Node.js server side:
var io = require('socket.io');
var express = require('express')

    var app = express()
      , server = require('http').createServer(app)
      , io = io.listen(server)

    server.listen(8088)

    io.sockets.on('connection', function(socket) {
      socket.on('message', function(data) {
        console.log(data)
      });
    });

I see this at the server side:
...
debug - websocket writing 1::
here is a test message
here is a test message
info - transport end (socket end)
...

How does namespace work ?

Hello,

Im trying to use namespace but it didn't work.
Here's the code I used :

client:

var socket = io('/chat');

server :

server, err := socketio.NewServer(nil)
if err != nil {
    log.Fatal(err)
}

server.Of("/chat").On("connection", func(so socketio.Socket) {
    log.Println("on connection")
}
server.On("error", func(so socketio.Socket, err error) {
    log.Println("error:", err)
})

When I ran the program, it didn't show "on connection".
Why is it not working?

Adding multiple empty callbacks will only let the first one work one time

For my use-case I'd like all communication to flow via socket.io, so I only have to implement authentication once, for this reason I have setup a number of GetData methods which returns the snapshot data needed.

What I'm seeing is that only the first emit with callback ever gets executed, subsequent calls will be ignored.

Can anyone tell me in what area I should start looking? I'm not that familiar with go yet, but willing to learn.

Attached the go / html / javascript I used to created this issue.

package main

import (
    "fmt"
    "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.On("getInitialData1", func() string {
            fmt.Println("getInitialData1 called")
            return "initialData1"
        })
        so.On("getInitialData2", func() string {
            fmt.Println("getInitialData2 called")
            return "initialData2"
        })
        so.On("getInitialData3", func() string {
            fmt.Println("getInitialData3 called")
            return "initialData3"
        })
        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 the following client html/javascript (based on the example)

<!doctype html>
<html>
  <head>
    <title>Socket.IO test</title>
  </head>
  <body>
    <ul id="log"></ul>
    <form id="form1">
      <input id="m" autocomplete="off" /><button>SendBad</button>
    </form>
    <script src="/socket.io.js"></script>
    <script src="/jquery-1.11.1.js"></script>
    <script>
      var socket = io();
      var appendToLog = function (message) {
        $('#log').append($('<li>').text(message));
      };
      $('#form1').submit(function(){

        socket.emit('getInitialData1', function (message) {
          appendToLog('getInitialData1Result: ' + message);
        });
        socket.emit('getInitialData2', function (message) {
          appendToLog('getInitialData2Result: ' + message);
        });
        socket.emit('getInitialData3', function (message) {
          appendToLog('getInitialData3Result: ' + message);
        });
        return false;
      });     
    </script>
  </body>
</html>

Long Polling

Hi. First of all, thank you for working at this library. Do you have any plans about adding long polling support?

when calling server side functions without specifying arguments, the client connection will break without errors

Given this function on the go side of things:

server.On("connection", func(so socketio.Socket) {
    so.On("getInitialData1", func() string {
        fmt.Println("getInitialData1 called")
        return "initialData1"
    })
})
server.On("error", func(so socketio.Socket, err error) {
    log.Println("error:", err)
})

and this function on the js side of things:

socket.emit('getInitialData1', function (message) {
    appendToLog('getInitialData1Result: ' + message);
});

When I execute the emit for the first time, the message returns with a value of undefined.

Then when I execute the emit again nothing appears to work and the connection with the server seems to be in an invalid state.

If you need any more information please let me know.

Difference in broadcast and emit

I've found a strange problem with a difference between emit and broadcast. My basic code was sending an array via emit on connection and to all connected clients periodically via broadcast. However I was finding that the client worked correctly on from the emit, but didn't work from the broadcast.

Debugging on the server I could see that the array was sent correctly from the emit, but was sent as an array of arrays on the broadcast.

As an example. I was sending the an array of structs
type eg struct { ts uint64 text string }

data := []eg{eg{ts: 1, text: "a"}, eg{ts: 2, text: "b"}}

when I do socket.Emit("update", data) I see the following go over the network
["update",[{"ts":1,"text":"a"},{"ts":2,"text":"b"}]]

However when I do socket.Broadcast("room","update",data) I see something different
["update",[[{"ts":1,"text":"a"},{"ts":2,"text":"b"}]]]

The difference being that there is now an array of arrays of eg.

I tracked this down to sometimes passing arguments as arrays and sometimes passing them as variable arguments.
The Send method in BroadcastAdaptor currently takes declares args as []interface{}. Changing this and all implementations to ...interface{} and whenever Send is called, pass arguments in as args...

I've got this working locally and will submit a pull request shortly.

Support for acknowledgment functions?

Hi @googollee

It doesn't seem that go-socket.io supports acknowledgment functions, just by taking a quick look through the docs+code.

Do you think they are technically possible (did you attempt to implement them)? If so would you accept a PR against the 0.9 branch for them?

CORS issue

I came across the same issue as #33 .

I'm not sure if it is just the CORS headers. As mentioned in the Engine IO JS library:

"Unlike the previous Socket.IO core, it always establishes a long-polling connection first, then tries to upgrade to better transports that are "tested" on the side."

The client polls before testing other connection methods. Which results in:

XMLHttpRequest cannot load http://myserver.com:9001/socket.io/?EIO=3&transport=polling&t=1416482712003-0. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:1234' is therefore not allowed access.

Is this merely the missing CORS headers? Or can't Go Socket IO handle these requests yet?

I'm using the Socket IO JS client v1.2, but having the exact same issues with v0.9.x.

Server broadcast method

Is there any way to emit some message from a server (not from a socket)?
I mean equivalent of node.js code
var io = require('socket.io')(80);
io.to('some room').emit('some event'):

utf-8 buggy in websocket transport?

I am using the latest socket.io client and go-socket.io server.
I am emitting the event name and an argument from socket.io-client using:

s.emit('quack','日本語');

If I specifiy "websocket" as the only transport in the client, apparently when you send messages in utf-8 the text gets garbled. If i specify "polling", all is well with the world.
From what I have checked from the go-socket.io's source code, the websocket transport is made possible by gorilla's websocket implementation. I tried replacing polling-xhr.go's r.Body with a proxy io.Reader and did the same for websocket.go's r from conn.NextReader(). When I printed the results I got:

polling: 000203ff34325b22717561636b222c22e697a5e69cace8aa9e225d
websocket:         325b22717561636b222c22c3a6c297c2a5c3a6c29cc2acc3a8c2aac29e225d

As you can see only the part 325b22717561636b222c22 and 9e225d (corresponding to 2["quack"," and "]) match. What's in between (is supposed to? but) doesn't match.

By the way, it works fine with socket.io-server and socket-io-client, so I am assuming this is either a bug in gorilla/websocket or go-socket.io?

caller reflection bug

There is a bug easily reproduced by doing a socket.emit('eventname','arg1', ..., 'argn') on the client and a matching so.On('eventname', func(arg1 string, ... different argn)
The server crashes if I pass more or even less arguments than the ones I specified server-side.

Not able to make namespaces work

I'm trying to create a namespace, but I'm not able to connect to the namespace from the client side.

Server:

func registerHandlers(server *socketio.Server) {
    server.Of("room1").On("connect", connectionHandler)
}

func connectionHandler(so socketio.Socket) {
    log.Println("on connection")
    so.Join("chat")
    so.On("chat message", func(msg string) {
        so.BroadcastTo("chat", "chat message", msg)
    })
}

Client:

var socket = io.connect("http://localhost:3000/room1");
socket.on('chat message', function(msg){
        $('#messages').append($('<li>').text(msg));
      });

Am I missing something?

reference to socket outside of server

Is it possible to get a reference to the server outside of the Server instance. Basically, I want to simply broadcast events from another go routine to all connected clients, and I havent come up with a good way to do it. Now I am keeping a map of ID and socketio.Socket, then on each new event, I do:

for _, client := range clients {
  client.BroadcastTo(sioRoom, messagType, msg)
}

This doesnt seem like the right approach though, so wondering if there is a better pattern.

Include a license document

A license document is missing from the repo that says that this library (and your code) is licensed under the 3-clause BSD license.

connection stalled after emitting unregistered event

Sorry for posting lots of issues in such a short time :(

Anyway, I have noticed that if I s.emit('omg'); on client side and I have no so.On("omg", func...{}); listener server-side, the next event emissions will never reach the server.

Apparently if the packet is ignored the io stream never gets read and it gets "lost" (blocked), with new emit's being ignored.

If I do (in handler.go):

func (h *socketHandler) onPacket(decoder *decoder, packet *packet) ([]interface{}, error) {
...
    if !ok {
        packet.Data = &[]interface{}{}
        decoder.DecodeData(packet)
        return nil, nil
    }

it works, but I am unsure if this is the right fix, especially when it concerns to doing more than actually required (parsing json, etc. seems unecessary). But I noticed you are actually adjusting v.Type inside DecodeData so that seems to be necessary...

Additionally, if I add something like the following to parser.go

func (d *decoder) IgnoreData() {
    if d.current == nil {
        return
    }
    defer func() {
        d.currentCloser.Close()
        d.current = nil
        d.currentCloser = nil
    }()
}

and call decoder.IgnoreData(); it also works (apparently by consuming the packet letting the next ones be read).

I have been thinking, it would actually be cool (security-wise) to have some sort of "so.OnUnhandled(func(event string, ...)" kinda feature on go-socket.io so we could disconnect bad clients, etc.

How to use the SetSessionManager for scaling?

As far as I can see, there's no way to serialize connections, store them in a database, retrieve them and reconstruct them, so how would that be done? An example would be very useful.

Crashing all the time on windows

Hi,

I'm trying to use it on Windows with socket.io 1.2. Crashes within seconds and all the time.
Am I using wrong versions or something?

My Go side is example from the read.me and client side is from here: http://socket.io/get-started/chat/

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x30 pc=0x565638]

goroutine 33 [running]:
runtime.panic(0x6bfd00, 0x88cfe2)
c:/go/src/pkg/runtime/panic.c:279 +0x11f
github.com/googollee/go-engine%2eio.(_conn).NextWriter(0xc0820242a0, 0x0, 0x0, 0
x0, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-engine.io/conn.go:129 +0xc8
github.com/googollee/go-socket%2eio.(_encoder).encodePacket(0xc08208aa00, 0x2, 0
x0, 0x0, 0xffffffffffffffff, 0x626e20, 0xc08208a9c0, 0x0, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-socket.io/parser.go:93 +0x84
github.com/googollee/go-socket%2eio.(_encoder).Encode(0xc08208aa00, 0x2, 0x0, 0x
0, 0xffffffffffffffff, 0x626e20, 0xc08208a9c0, 0x0, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-socket.io/parser.go:81 +0xd7
github.com/googollee/go-socket%2eio.(_socket).send(0xc082040a50, 0xc08208a980, 0
x2, 0x2, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-socket.io/socket.go:78 +0x176

github.com/googollee/go-socket%2eio.(_socketHandler).Emit(0xc082009120, 0x70dc70
, 0xc, 0xc08208a980, 0x2, 0x2, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-socket.io/handler.go:77 +0x45
d
github.com/googollee/go-socket%2eio.(_socket).Emit(0xc082040a50, 0x70dc70, 0xc,
0xc082086b70, 0x1, 0x1, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-socket.io/socket.go:61 +0x89
github.com/googollee/go-socket%2eio.broadcast.Send(0xc082040450, 0x361d98, 0xc08
2040f90, 0xc082086aa7, 0x5, 0x70dc70, 0xc, 0xc082086b70, 0x1, 0x1, ...)
c:/go/packages/src/github.com/googollee/go-socket.io/adapter.go:54 +0x22
9
github.com/googollee/go-socket%2eio.(_socketHandler).BroadcastTo(0xc08208a3e0, 0
x6fc770, 0x4, 0x70dc70, 0xc, 0xc082086b70, 0x1, 0x1, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-socket.io/handler.go:116 +0x1
4a
main.func┬╖001(0xc082086aa0, 0x5)
C:/Users/Rytis/Desktop/io/main.go:19 +0x300
reflect.Value.call(0x63b880, 0xc082086590, 0x0, 0x130, 0x6f6570, 0x4, 0xc08208a8
a0, 0x1, 0x1, 0x0, ...)
c:/go/src/pkg/reflect/value.go:563 +0x1217
reflect.Value.Call(0x63b880, 0xc082086590, 0x0, 0x130, 0xc08208a8a0, 0x1, 0x1, 0
x0, 0x0, 0x0)
c:/go/src/pkg/reflect/value.go:411 +0xde
github.com/googollee/go-socket%2eio.(_caller).Call(0xc082096380, 0x361d98, 0xc08
2040f90, 0xc082086a70, 0x1, 0x1, 0x0, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-socket.io/caller.go:71 +0x3bb

github.com/googollee/go-socket%2eio.(_socketHandler).onPacket(0xc08208a3e0, 0xc0
82096440, 0xc0820964c0, 0x0, 0x0, 0x0, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-socket.io/handler.go:149 +0x2
a9
github.com/googollee/go-socket%2eio.(_socket).loop(0xc082040f90, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-socket.io/socket.go:125 +0x30
d
github.com/googollee/go-socket%2eio.func┬╖003(0xc082040f90)
c:/go/packages/src/github.com/googollee/go-socket.io/server.go:74 +0x2e
created by github.com/googollee/go-socket%2eio.(*Server).loop
c:/go/packages/src/github.com/googollee/go-socket.io/server.go:75 +0x10c

goroutine 16 [IO wait]:
net.runtime_pollWait(0x361700, 0x72, 0x0)
c:/go/src/pkg/runtime/netpoll.goc:146 +0x6d
net.(_pollDesc).Wait(0xc08205c170, 0x72, 0x0, 0x0)
c:/go/src/pkg/net/fd_poll_runtime.go:84 +0x4d
net.(_ioSrv).ExecIO(0xc082028020, 0xc08205c060, 0x7055b0, 0x8, 0xc0820865e0, 0xc
08205c780, 0x0, 0x0)
c:/go/src/pkg/net/fd_windows.go:188 +0x242
net.(_netFD).acceptOne(0xc08205c000, 0x78ac80, 0xc08200e380, 0x2, 0x2, 0xc08205c
060, 0xc082016ea0, 0x0, 0x0)
c:/go/src/pkg/net/fd_windows.go:546 +0x3c7
net.(_netFD).accept(0xc08205c000, 0x78ac80, 0x0, 0x0, 0x0)
c:/go/src/pkg/net/fd_windows.go:573 +0x187
net.(_TCPListener).AcceptTCP(0xc082028030, 0x448cda, 0x0, 0x0)
c:/go/src/pkg/net/tcpsock_posix.go:234 +0x64
net/http.tcpKeepAliveListener.Accept(0xc082028030, 0x0, 0x0, 0x0, 0x0)
c:/go/src/pkg/net/http/server.go:1947 +0x52
net/http.(_Server).Serve(0xc0820103c0, 0x3617b0, 0xc082028030, 0x0, 0x0)
c:/go/src/pkg/net/http/server.go:1698 +0x98
net/http.(*Server).ListenAndServe(0xc0820103c0, 0x0, 0x0)
c:/go/src/pkg/net/http/server.go:1688 +0x154
net/http.ListenAndServe(0x6f5630, 0x5, 0x0, 0x0, 0x0, 0x0)
c:/go/src/pkg/net/http/server.go:1778 +0x80
main.main()
C:/Users/Rytis/Desktop/io/main.go:32 +0x3b9

goroutine 19 [finalizer wait]:
runtime.park(0x415a30, 0x891c38, 0x88fda9)
c:/go/src/pkg/runtime/proc.c:1369 +0xac
runtime.parkunlock(0x891c38, 0x88fda9)
c:/go/src/pkg/runtime/proc.c:1385 +0x42
runfinq()
c:/go/src/pkg/runtime/mgc0.c:2644 +0xdd
runtime.goexit()
c:/go/src/pkg/runtime/proc.c:1445

goroutine 20 [chan receive]:
github.com/googollee/go-socket%2eio.(*Server).loop(0xc082008ac0)
c:/go/packages/src/github.com/googollee/go-socket.io/server.go:68 +0x85
created by github.com/googollee/go-socket%2eio.NewServer
c:/go/packages/src/github.com/googollee/go-socket.io/server.go:26 +0x176

goroutine 21 [IO wait]:
net.runtime_pollWait(0x361650, 0x72, 0x0)
c:/go/src/pkg/runtime/netpoll.goc:146 +0x6d
net.(_pollDesc).Wait(0xc08205c2f0, 0x72, 0x0, 0x0)
c:/go/src/pkg/net/fd_poll_runtime.go:84 +0x4d
net.(_ioSrv).ExecIO(0xc082028020, 0xc08205c1e0, 0x6fb050, 0x7, 0x78ac10, 0x0, 0x
0, 0x0)
c:/go/src/pkg/net/fd_windows.go:188 +0x242
net.(_netFD).Read(0xc08205c180, 0xc08205e000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
c:/go/src/pkg/net/fd_windows.go:458 +0x156
net.(_conn).Read(0xc082028038, 0xc08205e000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
c:/go/src/pkg/net/net.go:122 +0xee
net/http.(_liveSwitchReader).Read(0xc08204c228, 0xc08205e000, 0x1000, 0x1000, 0x
c08208a800, 0x0, 0x0)
c:/go/src/pkg/net/http/server.go:206 +0xb6
io.(_LimitedReader).Read(0xc082008d40, 0xc08205e000, 0x1000, 0x1000, 0x569c49, 0
x0, 0x0)
c:/go/src/pkg/io/io.go:399 +0xd7
bufio.(_Reader).fill(0xc082010480)
c:/go/src/pkg/bufio/bufio.go:97 +0x1ba
bufio.(_Reader).ReadSlice(0xc082010480, 0xc08205c20a, 0x0, 0x0, 0x0, 0x0, 0x0)
c:/go/src/pkg/bufio/bufio.go:298 +0x233
bufio.(_Reader).ReadLine(0xc082010480, 0x0, 0x0, 0x0, 0x423800, 0x0, 0x0)
c:/go/src/pkg/bufio/bufio.go:326 +0x70
net/textproto.(_Reader).readLineSlice(0xc082040690, 0x0, 0x0, 0x0, 0x0, 0x0)
c:/go/src/pkg/net/textproto/reader.go:55 +0xa4
net/textproto.(_Reader).ReadLine(0xc082040690, 0x0, 0x0, 0x0, 0x0)
c:/go/src/pkg/net/textproto/reader.go:36 +0x55
net/http.ReadRequest(0xc082010480, 0xc082023110, 0x0, 0x0)
c:/go/src/pkg/net/http/request.go:556 +0xce
net/http.(_conn).readRequest(0xc08204c200, 0x0, 0x0, 0x0)
c:/go/src/pkg/net/http/server.go:577 +0x27d
net/http.(_conn).serve(0xc08204c200)
c:/go/src/pkg/net/http/server.go:1132 +0x625
created by net/http.(_Server).Serve
c:/go/src/pkg/net/http/server.go:1721 +0x31a

goroutine 31 [select]:
github.com/googollee/go-engine%2eio.(*conn).pingLoop(0xc082024770)
c:/go/packages/src/github.com/googollee/go-engine.io/conn.go:254 +0x1a2
created by github.com/googollee/go-engine%2eio.newConn
c:/go/packages/src/github.com/googollee/go-engine.io/conn.go:85 +0x156

goroutine 25 [chan receive]:
github.com/googollee/go-engine%2eio.(_conn).NextReader(0xc0820242a0, 0x0, 0x0, 0
x0, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-engine.io/conn.go:119 +0x72
github.com/googollee/go-socket%2eio.(_decoder).Decode(0xc0820962c0, 0xc082096300
, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-socket.io/parser.go:160 +0x76

github.com/googollee/go-socket%2eio.(_socket).loop(0xc082040a50, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-socket.io/socket.go:122 +0x2a
7
github.com/googollee/go-socket%2eio.func┬╖003(0xc082040a50)
c:/go/packages/src/github.com/googollee/go-socket.io/server.go:74 +0x2e
created by github.com/googollee/go-socket%2eio.(_Server).loop
c:/go/packages/src/github.com/googollee/go-socket.io/server.go:75 +0x10c

goroutine 29 [chan receive]:
github.com/googollee/go-engine%2eio.(_conn).NextReader(0xc082025260, 0x892528, 0
x0, 0x0, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-engine.io/conn.go:119 +0x72
github.com/googollee/go-socket%2eio.(_decoder).Decode(0xc082096600, 0xc082096640
, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-socket.io/parser.go:160 +0x76

github.com/googollee/go-socket%2eio.(_socket).loop(0xc082040de0, 0x0, 0x0)
c:/go/packages/src/github.com/googollee/go-socket.io/socket.go:122 +0x2a
7
github.com/googollee/go-socket%2eio.func┬╖003(0xc082040de0)
c:/go/packages/src/github.com/googollee/go-socket.io/server.go:74 +0x2e
created by github.com/googollee/go-socket%2eio.(_Server).loop
c:/go/packages/src/github.com/googollee/go-socket.io/server.go:75 +0x10c

goroutine 34 [runnable]:
github.com/googollee/go-engine%2eio.(*conn).onPacket(0xc082024770, 0xc082096880)

    c:/go/packages/src/github.com/googollee/go-engine.io/conn.go:238 +0x241

github.com/googollee/go-engine%2eio.(_websocket).ServeHTTP(0xc082096780, 0x36194
0, 0xc08203c6e0, 0xc082022ea0)
c:/go/packages/src/github.com/googollee/go-engine.io/websocket.go:79 +0x
1d6
github.com/googollee/go-engine%2eio.(_conn).serveHTTP(0xc082024770, 0x361940, 0x
c08203c6e0, 0xc082022ea0)
c:/go/packages/src/github.com/googollee/go-engine.io/conn.go:182 +0x1df
github.com/googollee/go-engine%2eio.(_Server).ServeHTTP(0xc08200c690, 0x361940,
0xc08203c6e0, 0xc082022ea0)
c:/go/packages/src/github.com/googollee/go-engine.io/server.go:128 +0x8f
1
github.com/googollee/go-socket%2eio.(_Server).ServeHTTP(0xc082008ac0, 0x361940,
0xc08203c6e0, 0xc082022ea0)
c:/go/packages/src/github.com/googollee/go-socket.io/server.go:63 +0x9d
net/http.(_ServeMux).ServeHTTP(0xc082040030, 0x361940, 0xc08203c6e0, 0xc082022ea
0)
c:/go/src/pkg/net/http/server.go:1511 +0x1aa
net/http.serverHandler.ServeHTTP(0xc0820103c0, 0x361940, 0xc08203c6e0, 0xc082022
ea0)
c:/go/src/pkg/net/http/server.go:1673 +0x1a6
net/http.(_conn).serve(0xc08204c580)
c:/go/src/pkg/net/http/server.go:1174 +0xa85
created by net/http.(*Server).Serve
c:/go/src/pkg/net/http/server.go:1721 +0x31a

Chat example

The included chat example seems to be broken. I can only see a bunch of:

2014/12/16 18:02:25
2014/12/16 18:02:25 emit:
2014/12/16 18:02:25 on disconnect
2014/12/16 18:02:26 on connection

in the logs but nothing happens in the browser if I try to send a message.

Thanks.

Binary support

The documentation indicates that go-socket.io has support for binary payloads, but for the life of me i can not get it to work. I can successfully emit binary payloads but can not receive them.

I am testing this with the socket.io server provided in the example dir. I have simply added the following

type binMessage struct {
    Payload *socketio.Attachment
}
...
        so.On("bin", func(msg binMessage) {
            log.Println("got binary message")
        })

Then updating the JS in index.html

var d = new Float32Array([1,2,3,4]).buffer;
socket.emit('bin', {Payload: d});

From what i can see, parser.decodeBinary(), a call to d.reader.NextReader() is made, but this call never completes.

func (d *decoder) decodeBinary(num int) ([][]byte, error) {
    ret := make([][]byte, num)
    for i := 0; i < num; i++ {
        t, r, err := d.reader.NextReader()
        if err != nil {
            return nil, err
        }

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

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 server crashes if a client leaves.

To reproduce,

Run the example included in the source. go run main.go
Connect two clients to http://localhost:5000/
Close one of those clients.
Send a chat message from the remaining client.

There seems to be a lingering conn lying around from the connection that was closed, but the transport is now nil. Perhaps the connection is not properly unregistered.

Console and Stack Traces:

880# go run main.go
2014/08/23 18:17:01 Serving at localhost:5000...
2014/08/23 18:17:03 on connection
2014/08/23 18:17:06 on connection
2014/08/23 18:17:28 emit: <nil>
2014/08/23 18:17:28 on disconnect
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x30 pc=0x167cf1]

goroutine 30 [running]:
runtime.panic(0x2b6080, 0x47d9c4)
    /usr/local/go/src/pkg/runtime/panic.c:279 +0xf5
github.com/googollee/go-engine%2eio.(*conn).NextWriter(0xc20802a230, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-engine.io/conn.go:129 +0xc1
github.com/googollee/go-socket%2eio.(*encoder).encodePacket(0xc20803eb00, 0x2, 0x0, 0x0, 0xffffffffffffffff, 0x21cf60, 0xc20803ea40, 0x0, 0x0, 0x0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/parser.go:93 +0x7d
github.com/googollee/go-socket%2eio.(*encoder).Encode(0xc20803eb00, 0x2, 0x0, 0x0, 0xffffffffffffffff, 0x21cf60, 0xc20803ea40, 0x0, 0x0, 0x0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/parser.go:81 +0xd0
github.com/googollee/go-socket%2eio.(*socket).send(0xc208022fc0, 0xc20803ea20, 0x2, 0x2, 0x0, 0x0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/socket.go:78 +0x16f
github.com/googollee/go-socket%2eio.(*socketHandler).Emit(0xc20803e880, 0x301450, 0xc, 0xc20803ea20, 0x2, 0x2, 0x0, 0x0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/handler.go:77 +0x456
github.com/googollee/go-socket%2eio.(*socket).Emit(0xc208022fc0, 0x301450, 0xc, 0xc208000ea0, 0x1, 0x1, 0x0, 0x0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/socket.go:61 +0x82
github.com/googollee/go-socket%2eio.broadcast.Send(0xc208022a80, 0x52fdb8, 0xc208023830, 0xc208000f20, 0x5, 0x301450, 0xc, 0xc208000ea0, 0x1, 0x1, ...)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/adapter.go:54 +0x222
github.com/googollee/go-socket%2eio.(*socketHandler).BroadcastTo(0xc20803ee60, 0x2f1250, 0x4, 0x301450, 0xc, 0xc208000ea0, 0x1, 0x1, 0x0, 0x0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/handler.go:116 +0x143
main.func·001(0xc208000da0, 0x7)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/example/main.go:20 +0x2f9
reflect.Value.call(0x2319c0, 0xc2080015f0, 0x0, 0x130, 0x2eb450, 0x4, 0xc20803e820, 0x1, 0x1, 0x0, ...)
    /usr/local/go/src/pkg/reflect/value.go:563 +0x1210
reflect.Value.Call(0x2319c0, 0xc2080015f0, 0x0, 0x130, 0xc20803e820, 0x1, 0x1, 0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/reflect/value.go:411 +0xd7
github.com/googollee/go-socket%2eio.(*caller).Call(0xc208034d40, 0x52fdb8, 0xc208023830, 0xc208000d70, 0x1, 0x1, 0x0, 0x0, 0x0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/caller.go:71 +0x3b4
github.com/googollee/go-socket%2eio.(*socketHandler).onPacket(0xc20803ee60, 0xc208034dc0, 0xc208034e00, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/handler.go:149 +0x2a2
github.com/googollee/go-socket%2eio.(*socket).loop(0xc208023830, 0x0, 0x0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/socket.go:125 +0x306
github.com/googollee/go-socket%2eio.func·003(0xc208023830)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/server.go:73 +0x27
created by github.com/googollee/go-socket%2eio.(*Server).loop
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/server.go:74 +0x105

goroutine 16 [IO wait]:
net.runtime_pollWait(0x52f720, 0x72, 0x0)
    /private/var/folders/00/0sdwh000h01000cxqpysvccm0035qk/T/makerelease003761064/go/src/pkg/runtime/netpoll.goc:146 +0x66
net.(*pollDesc).Wait(0xc20802a060, 0x72, 0x0, 0x0)
    /usr/local/go/src/pkg/net/fd_poll_runtime.go:84 +0x46
net.(*pollDesc).WaitRead(0xc20802a060, 0x0, 0x0)
    /usr/local/go/src/pkg/net/fd_poll_runtime.go:89 +0x42
net.(*netFD).accept(0xc20802a000, 0x37b238, 0x0, 0x52e3f0, 0x23)
    /usr/local/go/src/pkg/net/fd_unix.go:419 +0x343
net.(*TCPListener).AcceptTCP(0xc208032018, 0x47623, 0x0, 0x0)
    /usr/local/go/src/pkg/net/tcpsock_posix.go:234 +0x5d
net/http.tcpKeepAliveListener.Accept(0xc208032018, 0x0, 0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/http/server.go:1947 +0x4b
net/http.(*Server).Serve(0xc2080042a0, 0x52f7d0, 0xc208032018, 0x0, 0x0)
    /usr/local/go/src/pkg/net/http/server.go:1698 +0x91
net/http.(*Server).ListenAndServe(0xc2080042a0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/http/server.go:1688 +0x14d
net/http.ListenAndServe(0x2ea810, 0x5, 0x0, 0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/http/server.go:1778 +0x79
main.main()
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/example/main.go:33 +0x3b2

goroutine 19 [finalizer wait]:
runtime.park(0x15140, 0x480f90, 0x47fa89)
    /usr/local/go/src/pkg/runtime/proc.c:1369 +0x89
runtime.parkunlock(0x480f90, 0x47fa89)
    /usr/local/go/src/pkg/runtime/proc.c:1385 +0x3b
runfinq()
    /usr/local/go/src/pkg/runtime/mgc0.c:2644 +0xcf
runtime.goexit()
    /usr/local/go/src/pkg/runtime/proc.c:1445

goroutine 20 [chan receive]:
github.com/googollee/go-socket%2eio.(*Server).loop(0xc20803e4e0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/server.go:67 +0x7e
created by github.com/googollee/go-socket%2eio.NewServer
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/server.go:26 +0x16f

goroutine 21 [IO wait]:
net.runtime_pollWait(0x52f670, 0x72, 0x0)
    /private/var/folders/00/0sdwh000h01000cxqpysvccm0035qk/T/makerelease003761064/go/src/pkg/runtime/netpoll.goc:146 +0x66
net.(*pollDesc).Wait(0xc20802a140, 0x72, 0x0, 0x0)
    /usr/local/go/src/pkg/net/fd_poll_runtime.go:84 +0x46
net.(*pollDesc).WaitRead(0xc20802a140, 0x0, 0x0)
    /usr/local/go/src/pkg/net/fd_poll_runtime.go:89 +0x42
net.(*netFD).Read(0xc20802a0e0, 0xc208025000, 0x1000, 0x1000, 0x0, 0x52e3f0, 0x23)
    /usr/local/go/src/pkg/net/fd_unix.go:242 +0x34c
net.(*conn).Read(0xc208032020, 0xc208025000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/net.go:122 +0xe7
net/http.(*liveSwitchReader).Read(0xc20804e2a8, 0xc208025000, 0x1000, 0x1000, 0x8, 0x0, 0x0)
    /usr/local/go/src/pkg/net/http/server.go:206 +0xaf
io.(*LimitedReader).Read(0xc20803e0e0, 0xc208025000, 0x1000, 0x1000, 0x100000000000003, 0x0, 0x0)
    /usr/local/go/src/pkg/io/io.go:399 +0xd0
bufio.(*Reader).fill(0xc208004300)
    /usr/local/go/src/pkg/bufio/bufio.go:97 +0x1b3
bufio.(*Reader).ReadSlice(0xc208004300, 0x58590a, 0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/bufio/bufio.go:298 +0x22c
bufio.(*Reader).ReadLine(0xc208004300, 0x0, 0x0, 0x0, 0x22d00, 0x0, 0x0)
    /usr/local/go/src/pkg/bufio/bufio.go:326 +0x69
net/textproto.(*Reader).readLineSlice(0xc208023230, 0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/textproto/reader.go:55 +0x9d
net/textproto.(*Reader).ReadLine(0xc208023230, 0x0, 0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/textproto/reader.go:36 +0x4e
net/http.ReadRequest(0xc208004300, 0xc208029040, 0x0, 0x0)
    /usr/local/go/src/pkg/net/http/request.go:556 +0xc7
net/http.(*conn).readRequest(0xc20804e280, 0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/http/server.go:577 +0x276
net/http.(*conn).serve(0xc20804e280)
    /usr/local/go/src/pkg/net/http/server.go:1132 +0x61e
created by net/http.(*Server).Serve
    /usr/local/go/src/pkg/net/http/server.go:1721 +0x313

goroutine 25 [chan receive]:
github.com/googollee/go-engine%2eio.(*conn).NextReader(0xc20802a230, 0x52fdb8, 0x0, 0x0, 0x0, 0x0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-engine.io/conn.go:119 +0x6b
github.com/googollee/go-socket%2eio.(*decoder).Decode(0xc2080346c0, 0xc208034700, 0x0, 0x0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/parser.go:160 +0x6f
github.com/googollee/go-socket%2eio.(*socket).loop(0xc208022fc0, 0x0, 0x0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/socket.go:122 +0x2a0
github.com/googollee/go-socket%2eio.func·003(0xc208022fc0)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/server.go:73 +0x27
created by github.com/googollee/go-socket%2eio.(*Server).loop
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/server.go:74 +0x105

goroutine 27 [IO wait]:
net.runtime_pollWait(0x52f510, 0x72, 0x0)
    /private/var/folders/00/0sdwh000h01000cxqpysvccm0035qk/T/makerelease003761064/go/src/pkg/runtime/netpoll.goc:146 +0x66
net.(*pollDesc).Wait(0xc20802b020, 0x72, 0x0, 0x0)
    /usr/local/go/src/pkg/net/fd_poll_runtime.go:84 +0x46
net.(*pollDesc).WaitRead(0xc20802b020, 0x0, 0x0)
    /usr/local/go/src/pkg/net/fd_poll_runtime.go:89 +0x42
net.(*netFD).Read(0xc20802afc0, 0xc208081000, 0x1000, 0x1000, 0x0, 0x52e3f0, 0x23)
    /usr/local/go/src/pkg/net/fd_unix.go:242 +0x34c
net.(*conn).Read(0xc2080320c8, 0xc208081000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/net.go:122 +0xe7
net/http.(*liveSwitchReader).Read(0xc20804e8a8, 0xc208081000, 0x1000, 0x1000, 0x8, 0x0, 0x0)
    /usr/local/go/src/pkg/net/http/server.go:206 +0xaf
io.(*LimitedReader).Read(0xc20803ece0, 0xc208081000, 0x1000, 0x1000, 0x100000000000003, 0x0, 0x0)
    /usr/local/go/src/pkg/io/io.go:399 +0xd0
bufio.(*Reader).fill(0xc2080046c0)
    /usr/local/go/src/pkg/bufio/bufio.go:97 +0x1b3
bufio.(*Reader).ReadSlice(0xc2080046c0, 0x5ad90a, 0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/bufio/bufio.go:298 +0x22c
bufio.(*Reader).ReadLine(0xc2080046c0, 0x0, 0x0, 0x0, 0x22d00, 0x0, 0x0)
    /usr/local/go/src/pkg/bufio/bufio.go:326 +0x69
net/textproto.(*Reader).readLineSlice(0xc208022cc0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/textproto/reader.go:55 +0x9d
net/textproto.(*Reader).ReadLine(0xc208022cc0, 0x0, 0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/textproto/reader.go:36 +0x4e
net/http.ReadRequest(0xc2080046c0, 0xc2080288f0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/http/request.go:556 +0xc7
net/http.(*conn).readRequest(0xc20804e880, 0x0, 0x0, 0x0)
    /usr/local/go/src/pkg/net/http/server.go:577 +0x276
net/http.(*conn).serve(0xc20804e880)
    /usr/local/go/src/pkg/net/http/server.go:1132 +0x61e
created by net/http.(*Server).Serve
    /usr/local/go/src/pkg/net/http/server.go:1721 +0x313

goroutine 28 [select]:
github.com/googollee/go-engine%2eio.(*conn).pingLoop(0xc20802b110)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-engine.io/conn.go:254 +0x19b
created by github.com/googollee/go-engine%2eio.newConn
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-engine.io/conn.go:85 +0x14f

goroutine 31 [runnable]:
github.com/googollee/go-engine%2eio.(*conn).onPacket(0xc20802b110, 0xc208034580)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-engine.io/conn.go:238 +0x23a
github.com/googollee/go-engine%2eio.(*websocket).ServeHTTP(0xc208034380, 0x52f960, 0xc2080500a0, 0xc208028410)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-engine.io/websocket.go:79 +0x1cf
github.com/googollee/go-engine%2eio.(*conn).serveHTTP(0xc20802b110, 0x52f960, 0xc2080500a0, 0xc208028410)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-engine.io/conn.go:182 +0x1d8
github.com/googollee/go-engine%2eio.(*Server).ServeHTTP(0xc2080185f0, 0x52f960, 0xc2080500a0, 0xc208028410)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-engine.io/server.go:128 +0x8ea
github.com/googollee/go-socket%2eio.(*Server).ServeHTTP(0xc20803e4e0, 0x52f960, 0xc2080500a0, 0xc208028410)
    /Users/knorton/Documents/2014/08/404/src/github.com/googollee/go-socket.io/server.go:62 +0x49
net/http.(*ServeMux).ServeHTTP(0xc208022660, 0x52f960, 0xc2080500a0, 0xc208028410)
    /usr/local/go/src/pkg/net/http/server.go:1511 +0x1a3
net/http.serverHandler.ServeHTTP(0xc2080042a0, 0x52f960, 0xc2080500a0, 0xc208028410)
    /usr/local/go/src/pkg/net/http/server.go:1673 +0x19f
net/http.(*conn).serve(0xc20804ea00)
    /usr/local/go/src/pkg/net/http/server.go:1174 +0xa7e
created by net/http.(*Server).Serve
    /usr/local/go/src/pkg/net/http/server.go:1721 +0x313
exit status 2

Access-Control-Allow-Origin

I'm attempting to use go-socket.io on a separate hostname to the main website which is not part of the Go application. How should I add custom headers (e.g. Access-Control-Allow-Origin) to the initial HTTP responses sent back from go-socket.io?

server crashes

Hi,

I am using the simple use case: server emits something to client. And I get this crash:

        /usr/local/go/src/pkg/net/fd_poll_runtime.go:84 +0x46
net.(*pollDesc).WaitRead(0xc20802a680, 0x0, 0x0)
        /usr/local/go/src/pkg/net/fd_poll_runtime.go:89 +0x42
net.(*netFD).Read(0xc20802a620, 0xc2080c0900, 0x2800, 0x2800, 0x0, 0x7f550a6b5418, 0xb)
        /usr/local/go/src/pkg/net/fd_unix.go:232 +0x34c
net.(*conn).Read(0xc208036160, 0xc2080c0900, 0x2800, 0x2800, 0x0, 0x0, 0x0)
        /usr/local/go/src/pkg/net/net.go:122 +0xe7
bufio.(*Reader).fill(0xc208004a20)
        /usr/local/go/src/pkg/bufio/bufio.go:97 +0x1b3
bufio.(*Reader).Read(0xc208004a20, 0xc2080cf748, 0x2, 0x8, 0x2, 0x0, 0x0)
        /usr/local/go/src/pkg/bufio/bufio.go:175 +0x230
github.com/gorilla/websocket.(*Conn).readFull(0xc20809e0f0, 0xc2080cf748, 0x2, 0x8, 0x0, 0x0)
        /home/ubuntu/gopath/src/github.com/gorilla/websocket/conn.go:524 +0xb0
github.com/gorilla/websocket.(*Conn).advanceFrame(0xc20809e0f0, 0x68a1c0, 0x0, 0x0)
        /home/ubuntu/gopath/src/github.com/gorilla/websocket/conn.go:548 +0x166
github.com/gorilla/websocket.(*Conn).NextReader(0xc20809e0f0, 0x0, 0x0, 0x0, 0x0, 0x0)
        /home/ubuntu/gopath/src/github.com/gorilla/websocket/conn.go:688 +0x77
github.com/googollee/go-engine%2eio.(*websocket).ServeHTTP(0xc2080d4300, 0x7f550a6b6a30, 0xc20804c280, 0xc2080e6750)
        /home/ubuntu/gopath/src/github.com/googollee/go-engine.io/websocket.go:69 +0x111
github.com/googollee/go-engine%2eio.(*conn).serveHTTP(0xc20802bce0, 0x7f550a6b6a30, 0xc20804c280, 0xc2080e6750)
        /home/ubuntu/gopath/src/github.com/googollee/go-engine.io/conn.go:182 +0x1d8
github.com/googollee/go-engine%2eio.(*Server).ServeHTTP(0xc208018640, 0x7f550a6b6a30, 0xc20804c280, 0xc2080e6750)
        /home/ubuntu/gopath/src/github.com/googollee/go-engine.io/server.go:128 +0x8ea
github.com/googollee/go-socket%2eio.(*Server).ServeHTTP(0xc208032580, 0x7f550a6b6a30, 0xc20804c280, 0xc2080e6750)
        /home/ubuntu/gopath/src/github.com/googollee/go-socket.io/server.go:62 +0x49
net/http.(*ServeMux).ServeHTTP(0xc208022c30, 0x7f550a6b6a30, 0xc20804c280, 0xc2080e6750)
        /usr/local/go/src/pkg/net/http/server.go:1511 +0x1a3
net/http.serverHandler.ServeHTTP(0xc208004360, 0x7f550a6b6a30, 0xc20804c280, 0xc2080e6750)
        /usr/local/go/src/pkg/net/http/server.go:1673 +0x19f
net/http.(*conn).serve(0xc208046500)
        /usr/local/go/src/pkg/net/http/server.go:1174 +0xa7e
created by net/http.(*Server).Serve
        /usr/local/go/src/pkg/net/http/server.go:1721 +0x313

client on mac, chrome
server on ubuntu x64 go v1.3

Can not include js from localhost:5000

Hello,
When i start server.go which included your code to start port 5000, console alert that serving port 5000.
Then I try to include socket.io.js file on client:

<script src="http://localhost:5000/socket.io.js"></script>

but console log in browser alert that 404 file not found.
Can you show me how to connect with server ?

Not thread safe

The code is vulnerable to race conditions. Try run with go run -race

One example for all:
broadcast type in adapter.go uses unsynchronized access to the map (Join, Leave, Send)

thread-safe way for server to emit/broadcast?

Is there a thread-safe way to call socket.emit and server.BroadcastTo via server-initiated events? My use case is that the server will participate in a Redis pubsub, and relay those events to/from the sockets. The events will arrive from Redis asynchronously, so it's unclear to me how to safely deliver them to the sockets.

The usual way of handling events in go-socket.io is via server.On and socket.On, but those functions register callbacks that are handled in the server's goroutine loop and the socket goroutine loops respectively. In the Node model of course it would be safe to call emit/broadcastTo here, as there is only a single thread of execution, but not so in Golang.

Ideally I'd give each socket a channel from which to receive events, and then when a Redis event happens, I'd send it to the channel. Something similar to that is described in this example. But I can't see how to properly implement that in the current architecture.

Breaks after unknown emit.

The moment I emit something that isn't caught by the on listeners. It no longer responds to any other emit.

If I use the example code and emit

emit('chat message', "my text") // fine
emit('chat message', "my text") // fine
emit('chat msg', "my text") // fails as no listener
emit('chat message', "my text") // now fails

Also I am unable to transfer JSON objects, this also breaks everything?

Websocket returns 400 Bad Request

I'm looking into switching from Node.js to Golang.
However it seems websockets do not work properly with go-socket.io and instead return a 400 status code.
The same client-side code and browser work on a Node.js implementation.

Chrome returns this in the JavaScript console:
WebSocket connection to 'ws://example.com:5000/socket.io/?EIO=2&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 400

Client-side:

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.socket.io/socket.io-1.0.6.js"></script>
    <script type="text/javascript">
        var socket = io.connect('http://example.com:5000', {
            transports: ['websocket']
        });

        socket.on('connection', function() {
            console.log('Connected');
        });
    </script>
</head>
<body>
</body>
</html>

Malfunctioning Golang implementation:

package main

import (
    "fmt"
    "github.com/googollee/go-socket.io"
    "net/http"
)

func main() {
    server, err := socketio.NewServer(nil)
    if err != nil {
        panic(err)
    }

    server.On("connection", func(so socketio.Socket) {
        fmt.Println("Got a connection")
    })

    http.Handle("/socket.io/", server)

    fmt.Println("Serving at localhost:5000...")
    http.ListenAndServe(":5000", nil)
}

Functioning Node.js implementation:

var io = require('socket.io')(5000);

io.on('connection', function(socket) {
    console.log('Got a connection');
});

String doesn't get interpreted as array on node

Hello. Not sure if this is a problem on the node side or on the Go side. Basically, I'm trying to send an array to node.js like this.

socket.On("connect", func(ns *socketio.NameSpace) {
    fmt.Println("Connected!")
    ns.Emit("test", `["hello","world"]`)
})

Except on the node side, the message gets interpreted as [object String]. JavaScript socket.io clients create and send an array object with socket.emit("test", myArray) and node interprets that as [object Array]. Is there a flag or something I can set to tell node that my message should be interpreted as [object Array]?

I'm using Object.prototype.toString.call() to check the object's type.

Thanks!

race condition

If you build the example application with -race, and then run it, it reports a race condition:

$ go build -race
$ ./example
2014/10/15 19:50:18 Serving at localhost:5000...
2014/10/15 19:50:30 on connection
==================
WARNING: DATA RACE
Read by goroutine 7:
  github.com/googollee/go-engine%2eio.(*conn).serveHTTP()
      /Users/ojg/dev/go/src/github.com/googollee/go-engine.io/conn.go:148 +0x4b
  github.com/googollee/go-engine%2eio.(*Server).ServeHTTP()
      /Users/ojg/dev/go/src/github.com/googollee/go-engine.io/server.go:128 +0xb84
  github.com/googollee/go-socket%2eio.(*Server).ServeHTTP()
      /Users/ojg/dev/go/src/github.com/googollee/go-socket.io/server.go:62 +0x69
  net/http.(*ServeMux).ServeHTTP()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1511 +0x21c
  net/http.serverHandler.ServeHTTP()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1673 +0x1fc
  net/http.(*conn).serve()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1174 +0xf9e

Previous write by goroutine 16:
  github.com/googollee/go-engine%2eio.(*conn).serveHTTP()
      /Users/ojg/dev/go/src/github.com/googollee/go-engine.io/conn.go:179 +0x6c2
  github.com/googollee/go-engine%2eio.(*Server).ServeHTTP()
      /Users/ojg/dev/go/src/github.com/googollee/go-engine.io/server.go:128 +0xb84
  github.com/googollee/go-socket%2eio.(*Server).ServeHTTP()
      /Users/ojg/dev/go/src/github.com/googollee/go-socket.io/server.go:62 +0x69
  net/http.(*ServeMux).ServeHTTP()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1511 +0x21c
  net/http.serverHandler.ServeHTTP()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1673 +0x1fc
  net/http.(*conn).serve()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1174 +0xf9e

Goroutine 7 (running) created at:
  net/http.(*Server).Serve()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1721 +0x35d
  net/http.(*Server).ListenAndServe()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1688 +0x181
  net/http.ListenAndServe()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1778 +0xc3
  main.main()
      /Users/ojg/dev/go/src/github.com/googollee/go-socket.io/example/main.go:46 +0x44c

Goroutine 16 (running) created at:
  net/http.(*Server).Serve()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1721 +0x35d
  net/http.(*Server).ListenAndServe()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1688 +0x181
  net/http.ListenAndServe()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1778 +0xc3
  main.main()
      /Users/ojg/dev/go/src/github.com/googollee/go-socket.io/example/main.go:46 +0x44c
==================
==================
WARNING: DATA RACE
Read by goroutine 7:
  github.com/googollee/go-engine%2eio.(*conn).serveHTTP()
      /Users/ojg/dev/go/src/github.com/googollee/go-engine.io/conn.go:158 +0x2e6
  github.com/googollee/go-engine%2eio.(*Server).ServeHTTP()
      /Users/ojg/dev/go/src/github.com/googollee/go-engine.io/server.go:128 +0xb84
  github.com/googollee/go-socket%2eio.(*Server).ServeHTTP()
      /Users/ojg/dev/go/src/github.com/googollee/go-socket.io/server.go:62 +0x69
  net/http.(*ServeMux).ServeHTTP()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1511 +0x21c
  net/http.serverHandler.ServeHTTP()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1673 +0x1fc
  net/http.(*conn).serve()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1174 +0xf9e

Previous write by goroutine 16:
  github.com/googollee/go-engine%2eio.(*conn).serveHTTP()
      /Users/ojg/dev/go/src/github.com/googollee/go-engine.io/conn.go:177 +0x6f9
  github.com/googollee/go-engine%2eio.(*Server).ServeHTTP()
      /Users/ojg/dev/go/src/github.com/googollee/go-engine.io/server.go:128 +0xb84
  github.com/googollee/go-socket%2eio.(*Server).ServeHTTP()
      /Users/ojg/dev/go/src/github.com/googollee/go-socket.io/server.go:62 +0x69
  net/http.(*ServeMux).ServeHTTP()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1511 +0x21c
  net/http.serverHandler.ServeHTTP()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1673 +0x1fc
  net/http.(*conn).serve()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1174 +0xf9e

Goroutine 7 (running) created at:
  net/http.(*Server).Serve()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1721 +0x35d
  net/http.(*Server).ListenAndServe()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1688 +0x181
  net/http.ListenAndServe()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1778 +0xc3
  main.main()
      /Users/ojg/dev/go/src/github.com/googollee/go-socket.io/example/main.go:46 +0x44c

Goroutine 16 (running) created at:
  net/http.(*Server).Serve()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1721 +0x35d
  net/http.(*Server).ListenAndServe()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1688 +0x181
  net/http.ListenAndServe()
      /usr/local/Cellar/go/1.3.3/libexec/src/pkg/net/http/server.go:1778 +0xc3
  main.main()
      /Users/ojg/dev/go/src/github.com/googollee/go-socket.io/example/main.go:46 +0x44c
==================

HTTPS/WSS doesn't work

I can't get HTTPS/WSS to work.

The javascript client in the Chromium says net::ERR_INSECURE_RESPONSE.

I Firefox I get:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://localhost/socket.io/?EIO=3&transport=polling&t=1423162018973-1. This can be fixed by moving the resource to the same domain or enabling CORS.

My current code is:

package main

import (
    "database/sql"
    "flag"
    "log"
    "net/http"

    "github.com/gorilla/mux"
    _ "github.com/lib/pq"
    "github.com/googollee/go-socket.io"
)

func InitSocketIO() *socketio.Server {
    server, err := socketio.NewServer(nil)
    if err != nil {
        log.Fatal(err)
    }

    return server
}

func LogHandler(handler http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Printf("%s %s %q", r.RemoteAddr, r.Method, r.URL.String())
        handler.ServeHTTP(w, r)
    })
}

func redirect_to_https(w http.ResponseWriter, req *http.Request) {
    http.Redirect(w, req, "https://127.0.0.1"+req.RequestURI, http.StatusMovedPermanently)
}

func main() {
    // command-line args
    addr := flag.String("addr", "localhost:443", "Address on which to serve HTTPS")

    // Socket.IO
    server := InitSocketIO()

    // mux
    r := mux.NewRouter().StrictSlash(true)
    r.PathPrefix("/").Handler(http.FileServer(http.Dir("client")))
    http.Handle("/socket.io/", server)
    http.Handle("/", r)

    log.Printf("Listening on %s\n", *addr)
    go func() {
        if err := http.ListenAndServeTLS(*addr, "server.crt", "server.key", LogHandler(http.DefaultServeMux)); err != nil {
            log.Fatal(err)
        }
    }()

    if err := http.ListenAndServe(":80", http.HandlerFunc(redirect_to_https)); err != nil {
        log.Fatal(err)
    }

EDIT: Error was not related to this package at all, but was in the client code.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.