Golang 实现 websocket 通讯(一个服务器,两个客户端)

运行客户端时首先要输入自己的名字,两个客户端输入的名字不能一样。

先上运行结果:

服务器端:

客户端1:

客户端2:

话不多说,直接上代码:

服务器端:

Go 复制代码
package main

import (
	"fmt"
	"github.com/gorilla/websocket"
	"log"
	"net/http"
)

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

// Client represents a connected client
type Client struct {
	conn *websocket.Conn
}

// Message represents a message from a client
type Message struct {
	Sender    string `json:"sender"`
	Recipient string `json:"recipient"`
	Content   string `json:"content"`
}

var clients = make(map[*Client]bool)
var broadcast = make(chan Message)

func handleConnections(w http.ResponseWriter, r *http.Request) {
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println(err)
		return
	}
	defer conn.Close()

	client := &Client{conn: conn}
	clients[client] = true

	fmt.Println("Client connected")

	for {
		var msg Message
		err := conn.ReadJSON(&msg)
		if err != nil {
			log.Println(err)
			delete(clients, client)
			break
		}

		broadcast <- msg
	}
}

func handleMessages() {
	for {
		msg := <-broadcast

		for client := range clients {
			if client.conn != nil {
				err := client.conn.WriteJSON(msg)
				if err != nil {
					log.Println(err)
					client.conn.Close()
					delete(clients, client)
				}
			}
		}
	}
}

func main() {
	http.HandleFunc("/", handleConnections)
	go handleMessages()

	fmt.Println("WebSocket server listening on :8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}

客户端1:

Go 复制代码
package main

import (
	"bufio"
	"fmt"
	"github.com/gorilla/websocket"
	"log"
	"os"
)

type Message struct {
	Sender    string `json:"sender"`
	Recipient string `json:"recipient"`
	Content   string `json:"content"`
}

func main() {
	conn, _, err := websocket.DefaultDialer.Dial("ws://localhost:8080", nil)
	if err != nil {
		log.Println("Error connecting to server:", err)
		return
	}
	defer conn.Close()

	go func() {
		for {
			var msg Message
			err := conn.ReadJSON(&msg)
			if err != nil {
				log.Println("Error reading message:", err)
				return
			}
			fmt.Printf("Received from %s: %s\n", msg.Sender, msg.Content)
		}
	}()

	fmt.Print("Enter your name: ")
	var name string
	fmt.Scanln(&name)

	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		message := scanner.Text()
		msg := Message{Sender: name, Content: message}
		err := conn.WriteJSON(msg)
		if err != nil {
			log.Println("Error sending message:", err)
			return
		}
	}
}

客户端2:

Go 复制代码
package main

import (
	"bufio"
	"fmt"
	"github.com/gorilla/websocket"
	"log"
	"os"
)

type Message struct {
	Sender    string `json:"sender"`
	Recipient string `json:"recipient"`
	Content   string `json:"content"`
}

func main() {
	conn, _, err := websocket.DefaultDialer.Dial("ws://localhost:8080", nil)
	if err != nil {
		log.Println("Error connecting to server:", err)
		return
	}
	defer conn.Close()

	go func() {
		for {
			var msg Message
			err := conn.ReadJSON(&msg)
			if err != nil {
				log.Println("Error reading message:", err)
				return
			}
			fmt.Printf("Received from %s: %s\n", msg.Sender, msg.Content)
		}
	}()

	fmt.Print("Enter your name: ")
	var name string
	fmt.Scanln(&name)

	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		message := scanner.Text()
		msg := Message{Sender: name, Content: message}
		err := conn.WriteJSON(msg)
		if err != nil {
			log.Println("Error sending message:", err)
			return
		}
	}
}
相关推荐
NEGl DRYN2 分钟前
Go基础之环境搭建
开发语言·后端·golang
初心未改HD7 分钟前
Go Modules:依赖管理的完全指南
开发语言·golang
techdashen17 分钟前
把 Matrix 聊天服务器搬到 Serverless 上,还顺便免费升级了量子加密
运维·服务器·serverless
x-cmd18 分钟前
agent-browser 源码分析(二):WebSocket CDP 客户端
websocket·rust·cdp·json-rpc·agent-browser
rOuN STAT27 分钟前
Golang 构建学习
开发语言·学习·golang
似水এ᭄往昔30 分钟前
【Linux】--文件系统之软硬链接
linux·运维·服务器
乌萨奇也要立志学C++42 分钟前
【Linux】Socket编程UDP Echo 服务器→翻译服务器→多人聊天室
linux·服务器·udp
不甘先生1 小时前
Go context 实战指南:从入门到生产级并发控制(架构师避坑手册)
开发语言·后端·golang
yyuuuzz1 小时前
国际云服务器的技术特性与使用场景
运维·服务器
代码中介商1 小时前
Linux多线程编程进阶:fork与锁的交互及网络编程入门
linux·运维·服务器