多房间聊天室 websocket(一)

由于之前工作需要做聊天系统, 给游戏服务做客服系统,就了解了go语言的websocket 。
之前没有做过这方面的,就在网上找go语言实现的多房间聊天室的文章博客什么的, 发现资料很少啊,就找到了一篇讲java实现多房间聊天室的,就借鉴了一下实现思路,还有github上第三方写的websocket库——github.com/gorilla/websocket 基本实现了功能。

这篇就先实现基本功能,也方便初学者理解,注释会写清楚一些,下一篇会结合go语言的channl与goroutine实现更复杂的功能;

服务器功能代码

此处提供的服务器功能代码,之前说过,客户端负责向服务器发送信息,服务器可以控制怎么处理这个信息。客户端的功能还是找 “websocket在线测试工具”实现的。

package main

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

// 实现多房间聊天室思路
//创建map以roomName为key,访问者请求连接为value;value可以是map,也可以是切片数组;
//因为房间内有多个请求连接,为记录用户和请求,此处以用户id为key,请求为value;
// {roomid:{uid:conn}} 
var rooms = make(map[string]map[int]*websocket.Conn)

var (
	// 服务器应用程序从HTTP请求处理程序调用Upgrader.Upgrade方法以获取* Conn;
	upgraderdd = websocket.Upgrader {
		// 读取存储空间大小
		ReadBufferSize:1024,
		// 写入存储空间大小
		WriteBufferSize:1024,
		// 允许跨域
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}
)

// 连接websocket进入房间,首先在请求里指定要进入的房间
//  (也可以先进入个人房间,再转入其他房间都可以的,就看怎么处理连接对象conn,在这里先指定房间了)
// 所以在请求里需要带两个参数,房间名roomid和用户id
func wsEcho(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	roomid:=r.Form["roomid"][0] //从请求里获取房价名roomid
	uidd:=r.Form["uid"][0]      // 从请求里获取用户id
	uid,_:=strconv.Atoi(uidd)
	fmt.Println("roomid:===",roomid)
	fmt.Println("uid:==",uid)
	// conn就是建立连接后的连接对象 
	conn,_ := upgraderdd.Upgrade(w, r, nil)

	defer conn.Close()

	func(conn *websocket.Conn){
		if rooms[roomid] == nil{
			rooms[roomid] = map[int]*websocket.Conn{uid: conn}
		}else {
			rooms[roomid][uid] = conn
		}
	}(conn)
	fmt.Println("rooms:==",rooms)
	
	for {
		// 某个链接发来数据data
		msgTy, data,_:= conn.ReadMessage()
		rooms[roomid][uid]=conn  //把房间名和用户id及连接对象conn保存到map里

		//把数据返给当前房间里(除自己)所有的链接
		for k,v :=range rooms[roomid]{
			if k==uid{
				continue
			}
			err := v.WriteMessage(msgTy,data)
			if err!=nil{
				log.Println("error:==",err)
			}
			log.Printf("Write msg to client: recved: %s \n",data)
		}
	}

}

func main() {
	http.HandleFunc("/",wsEcho)      // ws://127.0.0.1:8888/rom
	// 监听 地址 端口
	err := http.ListenAndServe(":8888", nil)
	if err != nil {
		log.Fatal("ListenAndServe", err.Error())
	}
}

结果

代码设置里有允许跨域请求,所以允许不同ip访问,但是端口要是“8888” ,所以测试用来三个ip来访问,我为了省事就只使用了一个房间,也可以多开几个连接,换不同的房间名就可以了。。。。
多房间聊天室 websocket(一)_第1张图片
多房间聊天室 websocket(一)_第2张图片
多房间聊天室 websocket(一)_第3张图片
如上三个图所示,三个请求是 :
ws://127.0.0.1:8888/?roomid=tang&uid=01
ws://127.0.0.2:8888/?roomid=tang&uid=02
ws://127.0.0.3:8888/?roomid=tang&uid=03
房间名为tang的房间里有三个连接,用户为01、02、03;
首先01发送“古筝计划”,02和03就收到此信息,
02发送“ 掩体计划”,01和03就收到此信息,
也可以同时有多个连接多个房间,只有一个房间内的用户才可以收到信息;
ws://127.0.0.1:8888/?roomid=tang&uid=01
ws://127.0.0.1:8888/?roomid=tang&uid=02
ws://127.0.0.1:8888/?roomid=zhao&uid=03
ws://127.0.0.1:8888/?roomid=zhao&uid=04
ws://127.0.0.1:8888/?roomid=zhao&uid=05

你可能感兴趣的:(多房间聊天室 websocket(一))