fiber使用websocket--多进程版本

多进程数据是隔离的,也就是说大部分时间不同的用户登录,其实不在一个进程,没办法直接通信

如果是单进程版本其实就跟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>

posted @ 2024-04-22 17:49  朝阳1  阅读(155)  评论(0)    收藏  举报