| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- package socketio
- import (
- "net/http"
- "sync"
- "github.com/googollee/go-engine.io"
- )
- // Socket is the socket object of socket.io.
- type Socket interface {
- // Id returns the session id of socket.
- Id() string
- // Rooms returns the rooms name joined now.
- Rooms() []string
- // Request returns the first http request when established connection.
- Request() *http.Request
- // On registers the function f to handle an event.
- On(event string, f interface{}) error
- // Emit emits an event with given args.
- Emit(event string, args ...interface{}) error
- // Join joins the room.
- Join(room string) error
- // Leave leaves the room.
- Leave(room string) error
- // Disconnect disconnect the socket.
- Disconnect()
- // BroadcastTo broadcasts an event to the room with given args.
- BroadcastTo(room, event string, args ...interface{}) error
- }
- type socket struct {
- *socketHandler
- conn engineio.Conn
- namespace string
- id int
- mu sync.Mutex
- }
- func newSocket(conn engineio.Conn, base *baseHandler) *socket {
- ret := &socket{
- conn: conn,
- }
- ret.socketHandler = newSocketHandler(ret, base)
- return ret
- }
- func (s *socket) Id() string {
- return s.conn.Id()
- }
- func (s *socket) Request() *http.Request {
- return s.conn.Request()
- }
- func (s *socket) Emit(event string, args ...interface{}) error {
- if err := s.socketHandler.Emit(event, args...); err != nil {
- return err
- }
- if event == "disconnect" {
- s.conn.Close()
- }
- return nil
- }
- func (s *socket) Disconnect() {
- s.conn.Close()
- }
- func (s *socket) send(args []interface{}) error {
- packet := packet{
- Type: _EVENT,
- Id: -1,
- NSP: s.namespace,
- Data: args,
- }
- encoder := newEncoder(s.conn)
- return encoder.Encode(packet)
- }
- func (s *socket) sendConnect() error {
- packet := packet{
- Type: _CONNECT,
- Id: -1,
- NSP: s.namespace,
- }
- encoder := newEncoder(s.conn)
- return encoder.Encode(packet)
- }
- func (s *socket) sendId(args []interface{}) (int, error) {
- s.mu.Lock()
- packet := packet{
- Type: _EVENT,
- Id: s.id,
- NSP: s.namespace,
- Data: args,
- }
- s.id++
- if s.id < 0 {
- s.id = 0
- }
- s.mu.Unlock()
- encoder := newEncoder(s.conn)
- err := encoder.Encode(packet)
- if err != nil {
- return -1, nil
- }
- return packet.Id, nil
- }
- func (s *socket) loop() error {
- defer func() {
- s.LeaveAll()
- p := packet{
- Type: _DISCONNECT,
- Id: -1,
- }
- s.socketHandler.onPacket(nil, &p)
- }()
- p := packet{
- Type: _CONNECT,
- Id: -1,
- }
- encoder := newEncoder(s.conn)
- if err := encoder.Encode(p); err != nil {
- return err
- }
- s.socketHandler.onPacket(nil, &p)
- for {
- decoder := newDecoder(s.conn)
- var p packet
- if err := decoder.Decode(&p); err != nil {
- return err
- }
- ret, err := s.socketHandler.onPacket(decoder, &p)
- if err != nil {
- return err
- }
- switch p.Type {
- case _CONNECT:
- s.namespace = p.NSP
- s.sendConnect()
- case _BINARY_EVENT:
- fallthrough
- case _EVENT:
- if p.Id >= 0 {
- p := packet{
- Type: _ACK,
- Id: p.Id,
- NSP: s.namespace,
- Data: ret,
- }
- encoder := newEncoder(s.conn)
- if err := encoder.Encode(p); err != nil {
- return err
- }
- }
- case _DISCONNECT:
- return nil
- }
- }
- }
|