zishang520/socket.io

如何实现回调功能

ctbsea opened this issue · 6 comments

Listener func(...any)
没有返回参数
怎么实现如下的回调功能
`
server.On("some:event", func(msg string) string {
return msg //Sending ack with data in msg back to client, using "return statement"
})

`

写了一个,可以用这个

type ClientMessage struct {
	UserName string `json:"username"`
	Payload  string `json:"payload"`
}

func Wrapper(event string, client *socket.Socket, handler func(client *socket.Socket, cliMsg *entities.ClientMessage) []byte) func(...any) {
	return func(datas ...any) {
		logrus.Infof("recive a client event: [%s], datas: %+v", event, datas)
		d, ok := datas[0].(string)
		if !ok || d == "" {
			logrus.Errorf("invalid data type: %+v", datas)
			return
		}

		clientMsg := &entities.ClientMessage{}
		if err := json.Unmarshal([]byte(d), clientMsg); err != nil {
			logrus.WithError(err).Errorf("invalid data type: %+v", datas)
			return
		}

		r := handler(client, clientMsg)
		if len(r) > 0 {
			client.Emit(event)
		}
	}
}

func EventHandler() {
	server := socket.NewServer(nil, nil)
	server.On("connection", func(clients ...any) {
		client := clients[0].(*socket.Socket)
		client.On("join", Wrapper("join", client, JoinEndpoint))
		client.On("disconnect", func(...any) {})
	})
}

func JoinEndpoint(client *socket.Socket, cliMsg *entities.ClientMessage) []byte {
	// do your biz
}

写了一个,可以用这个

type ClientMessage struct {
	UserName string `json:"username"`
	Payload  string `json:"payload"`
}

func Wrapper(event string, client *socket.Socket, handler func(client *socket.Socket, cliMsg *entities.ClientMessage) []byte) func(...any) {
	return func(datas ...any) {
		logrus.Infof("recive a client event: [%s], datas: %+v", event, datas)
		d, ok := datas[0].(string)
		if !ok || d == "" {
			logrus.Errorf("invalid data type: %+v", datas)
			return
		}

		clientMsg := &entities.ClientMessage{}
		if err := json.Unmarshal([]byte(d), clientMsg); err != nil {
			logrus.WithError(err).Errorf("invalid data type: %+v", datas)
			return
		}

		r := handler(client, clientMsg)
		if len(r) > 0 {
			client.Emit(event)
		}
	}
}

func EventHandler() {
	server := socket.NewServer(nil, nil)
	server.On("connection", func(clients ...any) {
		client := clients[0].(*socket.Socket)
		client.On("join", Wrapper("join", client, JoinEndpoint))
		client.On("disconnect", func(...any) {})
	})
}

func JoinEndpoint(client *socket.Socket, cliMsg *entities.ClientMessage) []byte {
	// do your biz
}

https://socket.io/zh-CN/docs/v4/client-api/#socketemiteventname-args-ack

我期望的是这种效果,你提供的代码再客户端无法直接通过response 获取到消息
image

Use this annotation example:

socket.io/socket/socket.go

Lines 273 to 286 in 5758644

// Emits to this client.
//
// io.On("connection", func(args ...any) {
// socket := args[0].(*socket.Socket)
// socket.Emit("hello", "world")
//
// // all serializable datastructures are supported (no need to call json.Marshal, But the map can only be of `map[string]any` type, currently does not support other types of maps)
// socket.Emit("hello", 1, "2", map[string]any{"3": []string{"4"}, "5": types.NewBytesBuffer([]byte{6})})
//
// // with an acknowledgement from the client
// socket.Emit("hello", "world", func(args []any, err error) {
// // ...
// })
// })

socket.io/socket/socket.go

Lines 325 to 353 in 5758644

// Emits an event and waits for an acknowledgement
//
// io.On("connection", func(args ...any) => {
// client := args[0].(*socket.Socket)
// // without timeout
// client.EmitWithAck("hello", "world")(func(args []any, err error) {
// if err == nil {
// fmt.Println(args) // one response per client
// } else {
// // some clients did not acknowledge the event in the given delay
// }
// })
//
// // with a specific timeout
// client.Timeout(1000 * time.Millisecond).EmitWithAck("hello", "world")(func(args []any, err error) {
// if err == nil {
// fmt.Println(args) // one response per client
// } else {
// // some clients did not acknowledge the event in the given delay
// }
// })
// })
//
// Return: a `func(func([]any, error))` that will be fulfilled when all clients have acknowledged the event
func (s *Socket) EmitWithAck(ev string, args ...any) func(func([]any, error)) {
return func(ack func([]any, error)) {
s.Emit(ev, append(args, ack)...)
}
}

For more information, please check the documentation: https://pkg.go.dev/github.com/zishang520/socket.io/v2@v2.0.5/socket#Socket.Emit

Use this annotation example:

socket.io/socket/socket.go

Lines 273 to 286 in 5758644

// Emits to this client.
//
// io.On("connection", func(args ...any) {
// socket := args[0].(*socket.Socket)
// socket.Emit("hello", "world")
//
// // all serializable datastructures are supported (no need to call json.Marshal, But the map can only be of `map[string]any` type, currently does not support other types of maps)
// socket.Emit("hello", 1, "2", map[string]any{"3": []string{"4"}, "5": types.NewBytesBuffer([]byte{6})})
//
// // with an acknowledgement from the client
// socket.Emit("hello", "world", func(args []any, err error) {
// // ...
// })
// })

socket.io/socket/socket.go

Lines 325 to 353 in 5758644

// Emits an event and waits for an acknowledgement
//
// io.On("connection", func(args ...any) => {
// client := args[0].(*socket.Socket)
// // without timeout
// client.EmitWithAck("hello", "world")(func(args []any, err error) {
// if err == nil {
// fmt.Println(args) // one response per client
// } else {
// // some clients did not acknowledge the event in the given delay
// }
// })
//
// // with a specific timeout
// client.Timeout(1000 * time.Millisecond).EmitWithAck("hello", "world")(func(args []any, err error) {
// if err == nil {
// fmt.Println(args) // one response per client
// } else {
// // some clients did not acknowledge the event in the given delay
// }
// })
// })
//
// Return: a `func(func([]any, error))` that will be fulfilled when all clients have acknowledged the event
func (s *Socket) EmitWithAck(ev string, args ...any) func(func([]any, error)) {
return func(ack func([]any, error)) {
s.Emit(ev, append(args, ack)...)
}
}

For more information, please check the documentation: https://pkg.go.dev/github.com/zishang520/socket.io/v2@v2.0.5/socket#Socket.Emit

上述提供的都是基于emit 主动发送消息后等待client ack

我是想实现on监听某个事件,当收到客户端消息的时候,处理完消息返回客户端一些消息,

官方案例

**Server**
io.on("connection", (socket) => {
  socket.on("hello", (arg, callback) => {
    console.log(arg);  //  "world"
    callback("got it");  //  **我问这个callback 对应的实现方式**
  });
});

**Client**
socket.emit("hello", "world", (response) => {
  console.log(response); // "got it"
});

Use this annotation example:

socket.io/socket/socket.go

Lines 273 to 286 in 5758644

// Emits to this client.
//
// io.On("connection", func(args ...any) {
// socket := args[0].(*socket.Socket)
// socket.Emit("hello", "world")
//
// // all serializable datastructures are supported (no need to call json.Marshal, But the map can only be of `map[string]any` type, currently does not support other types of maps)
// socket.Emit("hello", 1, "2", map[string]any{"3": []string{"4"}, "5": types.NewBytesBuffer([]byte{6})})
//
// // with an acknowledgement from the client
// socket.Emit("hello", "world", func(args []any, err error) {
// // ...
// })
// })

socket.io/socket/socket.go

Lines 325 to 353 in 5758644

// Emits an event and waits for an acknowledgement
//
// io.On("connection", func(args ...any) => {
// client := args[0].(*socket.Socket)
// // without timeout
// client.EmitWithAck("hello", "world")(func(args []any, err error) {
// if err == nil {
// fmt.Println(args) // one response per client
// } else {
// // some clients did not acknowledge the event in the given delay
// }
// })
//
// // with a specific timeout
// client.Timeout(1000 * time.Millisecond).EmitWithAck("hello", "world")(func(args []any, err error) {
// if err == nil {
// fmt.Println(args) // one response per client
// } else {
// // some clients did not acknowledge the event in the given delay
// }
// })
// })
//
// Return: a `func(func([]any, error))` that will be fulfilled when all clients have acknowledged the event
func (s *Socket) EmitWithAck(ev string, args ...any) func(func([]any, error)) {
return func(ack func([]any, error)) {
s.Emit(ev, append(args, ack)...)
}
}

For more information, please check the documentation: https://pkg.go.dev/github.com/zishang520/socket.io/v2@v2.0.5/socket#Socket.Emit

上述提供的都是基于emit 主动发送消息后等待client ack

我是想实现on监听某个事件,当收到客户端消息的时候,处理完消息返回客户端一些消息,

官方案例

**Server**
io.on("connection", (socket) => {
  socket.on("hello", (arg, callback) => {
    console.log(arg);  //  "world"
    callback("got it");  //  **我想知道有没有对应的这个callback 对应的实现**
  });
});

**Client**
socket.emit("hello", "world", (response) => {
  console.log(response); // "got it"
});

client

socket.emit("hello", "world", (response) => {
  console.log(response); // "i'm  join"
});

go

io.Of("/", nil).On("connection", func(args ...any) {
      socket := args[0].(*socket.Socket)
      socket.On("join", func(a ...any) {
            msg :=a[0]  // "word"
            // a[1]对应的是client 传递的 (response){}
	    a[1].(func([]interface{}, error))([]interface{}{"i'm  join"}, nil) 
     })
})