websocket入门(3)——网络对战版五子棋交互逻辑

环境

  1. 服务器端使用Nodejs6.9.4 + Express4.x + Socket.IO 2.02
  2. 客户端使用socket.io.js

名词和变量

游戏大厅

1. 建立连接后就认为在游戏大厅中;
2. 断开连接(比如关闭浏览器或者其他),认为离开游戏大厅;
3. 即使在【游戏房间】中,也依然认定其在游戏大厅;
4. 通过服务器端onlineUsers(Map结构)来存储在线用户(作为key);

游戏房间

1. 创建游戏后,创建的内容就是游戏房间;
2. 游戏房间变量存储以下内容:
2.1 玩家player存储黑方black,白方white;
2.2 观战者watcher(Set结构);
2.3 房间创建时间ctime(Number类型);
2.4 下棋数据steps(Array);
2.5 棋盘大小size(Number);
2.6 游戏结束标志roomover(Boolean);
2.7 游戏房间的编号roomID(Number);

在线用户onlineUsers(服务器端)

1. 以userSocket作为key,存储在线用户,以及该用户当前的游戏信息(房间号 + 角色);
2. 用户建立连接时,将其加入;
3. 用户退出房间时,从中删除(并找到其对应的游戏房间,从房间删除),通报该房间所有人;
4. 退出游戏大厅时,读取到该用户所在游戏信息。如果有则调用3
5. Map结构;
6. key是userSocket;
7. value是对象;
7.1 属性id是游戏ID;
7.2 属性role是游戏角色

开启的房间roomlist(服务器端)

1. Map结构,以roomID作为key,存储该房间的信息;
2. 游戏房间的具体数据查看关键词【游戏房间】;
3. 可以通过.size获取到当前已开启的游戏房间的房间数

1、服务器端

1.1、建立长连接connection

  1. 用户建立创长连接,回调函数出现socket变量;
  2. 将socket作为key,存储在onlineUsers中,值为null;

1.2、退出长连接disconnect

  1. 用户退出长连接,触发”disconnect”;
  2. 调用【退出游戏房间】相关逻辑;

1.3、创建游戏房间createRoom

  1. 检查该用户是否在房间中,如果在则禁止创建;
  2. 随机创建一个不重复的房间ID;
  3. 初始化该房间信息;
  4. 将该房间信息和房间ID,以kv形式添加到roomlist中;
  5. 返回该房间ID;
  6. 调用加入房间的API;(见下面)

1.4、加入房间userEnterRoom

  1. 需要参数roomID,userSocket(用户的socket),role(黑方、白方或者观战,无参数时默认为观战);
  2. 首先通过userSocket去查onlineUsers,看是否有值;
  3. 如果有值,则调用【退出游戏房间】相关逻辑;
  4. 从roomID查看roomlist,是否有该房间;
  5. 如果查不到则通知用户该房间不存在,返回;
  6. 如果找到该房间,首先检查是否有role,如果没有,则将其设置为watcher(观战);
  7. 检查该房间指定role是否有人,如果有人,则将用户添加到watcher位置,并通报用户该位置有人;
  8. 如果没有人,则将用户添加到该位置;
  9. 更新该角色的onlineUser中的值({roomID, role});
  10. 通报该房间内所有用户,有玩家进入,其角色为role;
  11. 通过roomID从list里拉取信息,然后对该房间内所有用户,调用【向用户更新房间信息】逻辑;

1.5、退出游戏房间leaveRoom

  1. 需要参数userSocket;
  2. 以socket作为key,尝试从onlineUsers拉取值;
  3. 如果值不为空,可以从其数据中拉取到房间ID和游戏角色;
  4. 从roomlist拉取到该游戏,删除该角色;
  5. 对该游戏房间中所有玩家,通报该玩家已经退出游戏;
  6. 从onlineUsers删除该用户;
  7. 如果notLeave不为true,对该房间内所有用户,调用【向用户更新房间信息】逻辑;

1.6、将某人踢出游戏房间kickRoom(不做)

  1. 先从发起方,拉取他的socket;
  2. 从socket拉取到roomID;
  3. 从roomID拉取到房间;
  4. 从发起方拉取到踢人的位置;
  5. 删除该角色;
  6. 对该游戏房间中所有玩家,通报该玩家被踢出游戏;
  7. 对该角色通报他被踢出游戏;
  8. 更新该角色的onlineUser中的值(null);

1.7、切换游戏角色changeRoomRole

  1. 需要参数userSocket和role;
  2. 从userSocket获游戏ID和游戏角色currentRole;
  3. 去roomlist找该房间,如果房间不存在则提示,并return(理论上不可能吧?但为了代码健壮性写上);
  4. 找确定该房间该位置是否有人,如果有人则提示,并return;
  5. 将当前用户添加到该位置;
  6. 从之前获取的角色位置,在游戏房间中找到,并删除该userSocket;
  7. 更新该角色的onlineUser中的值(当前有roomID和role);
  8. 向房间内所有用户,通报该用户角色切换;

1.8、向用户更新房间信息updateRoomRoom

  1. 需要参数roomID;
  2. 从roomlist拉取当前游戏房间用户的信息;
  3. 创建对象,里面添加进去黑方白方和观战者的信息;
  4. 遍历游戏房间的黑方、白方和观战方的userSocket,并向他们emit第三步的对象,emit的key是updateRoomRoom;

2、客户端

2.1、基本功能

  1. SETTING:设置棋子大小
  2. ROOMINFO:房间信息,从服务器同步到本地;
  3. USERINFO:目前只存储了用户名;
  4. init函数:初始化函数,当页面加载完成后执行(内含仿jQuery的简化选择器,连接websocket的后端服务器,DOM事件监听,socket.io事件监听);
  5. selector函数:使用document.querySelector和querySelectorAll来简化选择器操作;
  6. listenDomclickEvent函数:监听各种dom的点击事件,比如创建房间啦,加入房间啦,切换角色啦,开始新游戏啦之类;
  7. listenSocketEvent函数:监听服务器发送过来的socket.io事件;
  8. getName函数:生成随机姓名;
  9. getNowDate函数:生成事件戳;
  10. initBoard函数:通过房间信息,更新;
  11. createBox函数:生成棋盘的格子;
  12. createPiece函数:生成棋子;
  13. toMakePieceWhenHasStart函数:如果已经在下棋中,那么需要通过这个方法来生成棋盘上所有的棋子;
  14. resetRoomInfo函数:重置棋盘、房间信息;
  15. checkerboardClick函数:监听下棋下在哪里了;
  16. checkCanPutPiece函数:前端判定是否可以下这一步棋(后端会二次校验);
  17. GameOver函数:游戏结束后的处理;
  18. changeColor函数:切换下棋角色时的提示;

2.2、三种不同的提示

【函数】通过roomID向游戏内所有用户发送通知信息alertToRoom

  1. 当然需要参数roomID,需要参数信息内容;
  2. 通过roomID去从roomlist里找游戏;
  3. 遍历游戏里的每个人,调用emit发送信息,key是alertToRoom;

【函数】通过room去遍历每个用户forEachUserSocketInRoom

  1. 参数是从roomlist里找到的room,以及回调函数;
  2. 遍历每个角色,调用回调函数。回调函数参数一是该位置的userSocket,参数二是role

【消息key】通报给当前用户alertToUser

  1. 参数是对象,{msg:”“}

3、通信关键字

3.1、服务器端socket响应

connection

当用户和服务器建立长连接时触发

disconnect

用户断开链接(主动被动都会触发)

createRoom

用户创建游戏时触发

updateName

用户更新名字

leaveRoom

用户离开房间

userEnterRoom

用户进入房间

speakwords

用户发言(大厅或者room里)

restartRoom

当要求开始新的一局的请求发送时,判断游戏是否结束,黑方和白方是否都在(并且要是其中一方发起的),如果是,则返回信息初始化棋盘

3.2、客户端socket响应

connection-success

建立链接后,服务器端会发送这个过来

disconnect

断线时会触发本事件(无论是主动还是被动),提示用户断线了。

getCurrentName

获取当前姓名,当用户通过updateName推送姓名到服务器后,服务器端响应后会发送这个给客户端

tipsToUser

黑色 字体的系统消息

alertToUser

红色 字体的系统消息

alertToRoom

红色 字体系统消息,对房间内所有人推送时使用。

leaveRoom

蓝色 字体系统消息,用户离开房间时推送离开消息时使用。

chat-words

收到聊天信息时,推送到聊天栏。房间和大厅的聊天都会通过这个来获取

broadcast

广播信息,每个人都会收到。

userINFO

收到当前用户信息,暂时没用

转自: https://blog.csdn.net/qq20004604/article/details/73835546

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容