多进程数据是隔离的,也就是说处理不好,不同的用户登录,其实不在一个进程,没办法直接通信
解决办法:定义一个全局变量,所有进程公用,要加锁
如果是单进程版本其实就跟gin框架那些一样了多线程+channel不存在数据隔离的问题
main.go
package main
import (
"flag"
"fmt"
"log"
"sync"
"github.com/gofiber/contrib/websocket"
"github.com/gofiber/fiber/v2"
)
// Add more data to this type if needed
type client struct {
isClosing bool
mu sync.Mutex
}
// Note: although large maps with pointer-like types (e.g. strings) as keys are slow,
// using pointers themselves as keys is acceptable and fast
var clients = make(map[*websocket.Conn]*client)
func main() {
app := fiber.New(fiber.Config{
Prefork: true,
})
app.Static("/", "./home.html")
app.Use(func(c *fiber.Ctx) error {
if websocket.IsWebSocketUpgrade(c) { // Returns true if the client requested upgrade to the WebSocket protocol
return c.Next()
}
return c.SendStatus(fiber.StatusUpgradeRequired)
})
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
// When the function returns, unregister the client and close the connection
defer func() {
fmt.Println("触发了删除")
delete(clients, c)
c.Close()
}()
// Register the client
clients[c] = &client{}
log.Println(len(clients))
for {
messageType, message, err := c.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
log.Println("read error:", err)
}
return
}
if messageType == websocket.TextMessage {
// Broadcast the received message
for connection, c := range clients {
go func(connection *websocket.Conn, c *client) { // send to each client in parallel so we don't block on a slow client
c.mu.Lock()
defer c.mu.Unlock()
if c.isClosing {
return
}
if err := connection.WriteMessage(websocket.TextMessage, []byte(message)); err != nil {
c.isClosing = true
log.Println("write error:", err)
connection.WriteMessage(websocket.CloseMessage, []byte{})
connection.Close()
delete(clients, connection)
}
}(connection, c)
}
} else {
log.Println("websocket message received of type", messageType)
}
}
}))
addr := flag.String("addr", ":8080", "http service address")
flag.Parse()
log.Fatal(app.Listen(*addr))
}
html
<!-- See https://github.com/gorilla/websocket/blob/master/examples/chat/home.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Chat Example</title>
<script type="text/javascript">
window.onload = function () {
var conn;
var msg = document.getElementById("msg");
var log = document.getElementById("log");
function appendLog(item) {
var doScroll = log.scrollTop > log.scrollHeight - log.clientHeight - 1;
log.appendChild(item);
if (doScroll) {
log.scrollTop = log.scrollHeight - log.clientHeight;
}
}
document.getElementById("form").onsubmit = function () {
if (!conn) {
return false;
}
if (!msg.value) {
return false;
}
conn.send(msg.value);
msg.value = "";
return false;
};
if (window["WebSocket"]) {
conn = new WebSocket("ws://" + document.location.host + "/ws");
conn.onclose = function (evt) {
var item = document.createElement("div");
item.innerHTML = "<b>Connection closed.</b>";
appendLog(item);
};
conn.onmessage = function (evt) {
var messages = evt.data.split('\n');
for (var i = 0; i < messages.length; i++) {
var item = document.createElement("div");
item.innerText = messages[i];
appendLog(item);
}
};
} else {
var item = document.createElement("div");
item.innerHTML = "<b>Your browser does not support WebSockets.</b>";
appendLog(item);
}
};
</script>
<style type="text/css">
html {
overflow: hidden;
}
body {
overflow: hidden;
padding: 0;
margin: 0;
width: 100%;
height: 100%;
background: gray;
}
#log {
background: white;
margin: 0;
padding: 0.5em 0.5em 0.5em 0.5em;
position: absolute;
top: 0.5em;
left: 0.5em;
right: 0.5em;
bottom: 3em;
overflow: auto;
}
#form {
padding: 0 0.5em 0 0.5em;
margin: 0;
position: absolute;
bottom: 1em;
left: 0px;
width: 100%;
overflow: hidden;
}
</style>
</head>
<body>
<div id="log"></div>
<form id="form">
<input type="submit" value="Send" />
<input type="text" id="msg" size="64" autofocus autocomplete="off" />
</form>
</body>
</html>
标签:em,fiber,websocket,log,--,0.5,item,var
From: https://www.cnblogs.com/qcy-blog/p/18151124