多房间聊天室 websocket(一),我有辣条 跟我走的博客,websocket房间系统

香港256IP千兆站群服务器BGP专线240元起! 境内高防云服务器/云物理机百G高防全面上新! 华为云香港物理机精品线路全面上线![特价] 企业级CN2 GIA双程专线高速回国 T3机房 香港美国韩国海外独立物理服务器特价热销中!
由于之前工作需要做聊天系统, 给游戏服务做客服系统,就了解了go语言的websocket 。
之前没有做过这方面的,就在网上找go语言实现的多房间聊天室的文章博客什么的, 发现资料很少啊,就找到了一篇讲java实现多房间聊天室的,就借鉴了一下实现思路,还有github上第三方写的websocket库——github.com/gorilla/websocket 基本实现了功能。
这篇就先实现基本功能,也方便初学者理解,注释会写清楚一些,下一篇会结合go语言的channl与goroutine实现更复杂的功能;
服务器功能代码
此处提供的服务器功能代码,之前说过,客户端负责向服务器发送信息,服务器可以控制怎么处理这个信息。客户端的功能还是找 “websocket在线测试工具”实现的。
package mainimport ("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和用户idfunc wsEcho(w http.ResponseWriter, r *http.Request) { r.ParseForm()roomid:=r.Form["roomid"][0] //从请求里获取房价名roomiduidd:=r.Form["uid"][0] // 从请求里获取用户iduid,_:=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 { // 某个链接发来数据datamsgTy, 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来访问,我为了省事就只使用了一个房间,也可以多开几个连接,换不同的房间名就可以了。。。。
如上三个图所示,三个请求是 :
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