跳到主要内容
版本:websocket_v1.x.x

Socket.io

Release Discord Test

用于 Fiber 的 WebSocket 封装,支持事件,灵感来自 Socket.io

注意:需要 Go 1.20 及以上版本

安装

go get -u github.com/gofiber/fiber/v2
go get -u github.com/gofiber/contrib/socketio

签名

// Initialize new socketio in the callback this will
// execute a callback that expects kws *Websocket Object
// and optional config websocket.Config
func New(callback func(kws *Websocket), config ...websocket.Config) func(*fiber.Ctx) error
// Add listener callback for an event into the listeners list
func On(event string, callback func(payload *EventPayload))
// Emit the message to a specific socket uuids list
// Ignores all errors
func EmitToList(uuids []string, message []byte)
// Emit to a specific socket connection
func EmitTo(uuid string, message []byte) error
// Broadcast to all the active connections
// except avoid broadcasting the message to itself
func Broadcast(message []byte)
// Fire custom event on all connections
func Fire(event string, data []byte)

示例

package main

import (
"encoding/json"
"fmt"
"log"

"github.com/gofiber/contrib/socketio"
"github.com/gofiber/contrib/websocket"
"github.com/gofiber/fiber/v2"
)

// MessageObject Basic chat message object
type MessageObject struct {
Data string `json:"data"`
From string `json:"from"`
Event string `json:"event"`
To string `json:"to"`
}

func main() {

// The key for the map is message.to
clients := make(map[string]string)

// Start a new Fiber application
app := fiber.New()

// Setup the middleware to retrieve the data sent in first GET request
app.Use(func(c *fiber.Ctx) error {
// IsWebSocketUpgrade returns true if the client
// requested upgrade to the WebSocket protocol.
if websocket.IsWebSocketUpgrade(c) {
c.Locals("allowed", true)
return c.Next()
}
return fiber.ErrUpgradeRequired
})

// Multiple event handling supported
socketio.On(socketio.EventConnect, func(ep *socketio.EventPayload) {
fmt.Printf("Connection event 1 - User: %s", ep.Kws.GetStringAttribute("user_id"))
})

// Custom event handling supported
socketio.On("CUSTOM_EVENT", func(ep *socketio.EventPayload) {
fmt.Printf("Custom event - User: %s", ep.Kws.GetStringAttribute("user_id"))
// --->

// DO YOUR BUSINESS HERE

// --->
})

// On message event
socketio.On(socketio.EventMessage, func(ep *socketio.EventPayload) {

fmt.Printf("Message event - User: %s - Message: %s", ep.Kws.GetStringAttribute("user_id"), string(ep.Data))

message := MessageObject{}

// Unmarshal the json message
// {
// "from": "<user-id>",
// "to": "<recipient-user-id>",
// "event": "CUSTOM_EVENT",
// "data": "hello"
//}
err := json.Unmarshal(ep.Data, &message)
if err != nil {
fmt.Println(err)
return
}

// Fire custom event based on some
// business logic
if message.Event != "" {
ep.Kws.Fire(message.Event, []byte(message.Data))
}

// Emit the message directly to specified user
err = ep.Kws.EmitTo(clients[message.To], ep.Data, socketio.TextMessage)
if err != nil {
fmt.Println(err)
}
})

// On disconnect event
socketio.On(socketio.EventDisconnect, func(ep *socketio.EventPayload) {
// Remove the user from the local clients
delete(clients, ep.Kws.GetStringAttribute("user_id"))
fmt.Printf("Disconnection event - User: %s", ep.Kws.GetStringAttribute("user_id"))
})

// On close event
// This event is called when the server disconnects the user actively with .Close() method
socketio.On(socketio.EventClose, func(ep *socketio.EventPayload) {
// Remove the user from the local clients
delete(clients, ep.Kws.GetStringAttribute("user_id"))
fmt.Printf("Close event - User: %s", ep.Kws.GetStringAttribute("user_id"))
})

// On error event
socketio.On(socketio.EventError, func(ep *socketio.EventPayload) {
fmt.Printf("Error event - User: %s", ep.Kws.GetStringAttribute("user_id"))
})

app.Get("/ws/:id", socketio.New(func(kws *socketio.Websocket) {

// Retrieve the user id from endpoint
userId := kws.Params("id")

// Add the connection to the list of the connected clients
// The UUID is generated randomly and is the key that allow
// socketio to manage Emit/EmitTo/Broadcast
clients[userId] = kws.UUID

// Every websocket connection has an optional session key => value storage
kws.SetAttribute("user_id", userId)

//Broadcast to all the connected users the newcomer
kws.Broadcast([]byte(fmt.Sprintf("New user connected: %s and UUID: %s", userId, kws.UUID)), true, socketio.TextMessage)
//Write welcome message
kws.Emit([]byte(fmt.Sprintf("Hello user: %s with UUID: %s", userId, kws.UUID)), socketio.TextMessage)
}))

log.Fatal(app.Listen(":3000"))
}


支持的事件

常量事件描述
EventMessagemessage当接收到文本/二进制消息时触发
EventPingping更多详细信息在此
EventPongpong参考 ping 的描述
EventDisconnectdisconnect断开连接时触发。断开连接事件中提供的错误信息,定义在 RFC 6455 第 11.7 节。
EventConnectconnect首次连接时触发
EventCloseclose当连接由服务器主动关闭时触发。这与客户端断开连接不同
EventErrorerror出现错误时触发,也常用于调试 websockets

事件 Payload 对象

变量类型描述
Kws*Websocket连接对象
Namestring事件的名称
SocketUUIDstring唯一的连接 UUID
SocketAttributesmap[string]string可选的 websocket 属性
Errorerror(可选) 由断开连接或错误事件触发
Data[]byte在 Message 和 Error 事件中使用的载荷,包含自定义事件的载荷

Socket 实例函数

Name类型描述
SetAttributevoid为特定的 socket 连接设置一个特定的属性
GetUUIDstring获取 socket 连接的 UUID
SetUUIDerror设置 socket 连接的 UUID
GetAttributestring从 socket 属性中获取一个特定的属性
EmitToListvoid将消息发送到特定的 socket UUID 列表
EmitToerror发送到特定的 socket 连接
Broadcastvoid广播给所有活跃连接,但不包括广播消息给自己
Firevoid触发自定义事件
Emitvoid发送/写入消息到给定的连接
Closevoid从服务器主动关闭连接

注意:可以直接从实例访问 FastHTTP 连接

kws.Conn