Java后端使用socketio,实现小程序答题pk功能

本文介绍了如何利用SpringIoC容器管理和控制SocketIO服务的生命周期,包括自动启动和关闭机制,以及处理客户端连接、断开和自定义事件的方法。同时提到了作者提供的一份Java开发学习资源,涵盖了基础知识和进阶课程,旨在帮助开发者提升技能。
摘要由CSDN通过智能技术生成

*/

@PostConstruct

private void autoStartup() throws Exception {

start();

}

/**

  • Spring IoC容器在销毁SocketIOServiceImpl Bean之前关闭,避免重启项目服务端口占用问题

  • @throws Exception

*/

@PreDestroy

private void autoStop() throws Exception {

stop();

}

public void start() {

// 监听客户端连接,同级挑战比拼

socketIOServer.addConnectListener(client -> {

Long uid = Long.valueOf(getParamsByClient(client));

log.info(“connect come in,uid:{}”,uid);

//0为同级挑战,1为邀请好友pk

int type = 0;

//房间号

int pkId = 0;

//从请求的连接中拿出参数

Map<String, List> params = client.getHandshakeData().getUrlParams();

List list = params.get(“type”);

if (list != null && list.size() > 0) {

type = Integer.valueOf(list.get(0));

}

List list1 = params.get(“pkId”);

if (list1 != null && list1.size() > 0) {

pkId = Integer.valueOf(list1.get(0));

}

if (uid != null) {

if (clientMap.containsKey(uid)) {

log.info(uid + “is reconnect”);

clientMap.remove(uid);

clientMap.put(uid , client);

}else{

clientMap.put(uid, client);

log.info(“clientMap:”+clientMap);

joinSendMessage(uid , client , type , pkId);

}

}

});

// 监听客户端断开连接

socketIOServer.addDisconnectListener(client -> {

Long uid = Long.valueOf(getParamsByClient(client));

log.info(“disconnect come in,uid:{}”,uid);

if (uid != null) {

log.info(“uid is not null come in,uid:{}”,uid);

clientMap.remove(uid);

client.disconnect();

//退出通知对手

Long usrEntId = 0l;

PkGroup pkGroup = pkMapper.getPkGroupUserNewRoom(uid);

if(pkGroup != null){

log.info(“pkGroup is not null come in,uid:{}”,uid);

if(uid == pkGroup.getInviteUsrEntId()){

usrEntId = pkGroup.getAcceptUsrEntId();

}else if(uid == pkGroup.getAcceptUsrEntId()){

usrEntId = pkGroup.getInviteUsrEntId();

}

}

if(usrEntId != null && usrEntId != 0l){

log.info(“usrEntId is not null come in,uid:{}”,uid);

log.info(“socketIOClient usrEntId:” + usrEntId);

JSONObject jsonObject = new JSONObject();

SocketIOClient socketIOClient = clientMap.get(usrEntId);

if(socketIOClient != null){

jsonObject.put(“disconnect” , 1);

socketIOClient.sendEvent(“ClientReceive” , jsonObject);

}

}

if(clientMap.get(usrEntId) == null || usrEntId == null){

if(pkGroup != null){

PkGroup updatePkGroup = pkMapper.getPkGroupById(pkGroup.getId());

updatePkGroup.setState(2);

pkMapper.updatePkGroup(updatePkGroup);

log.info(“disconnect opponent is disconnect,uid:{}”,uid);

}

}

}

log.info(“disconnect is success,uid:{}”,uid);

});

// 处理自定义的事件,与连接监听类似

// 此示例中测试的json收发 所以接收参数为JSONObject 如果是字符类型可以用String.class或者Object.class

socketIOServer.addEventListener(“ServerReceive”,JSONObject.class, (client, data, ackSender) -> {

JSONObject jsonObject = data;

if(data != null){

String uid = jsonObject.getString(“usrEntId”);

String action = jsonObject.getString(“action”);

if(“getAI”.equals(action)){

log.info(“getAI come in,uid:{}”,uid);

//和人机pk返回

botSendMessage(uid , client);

}else if(“challenge”.equals(action)){

log.info(“challenge come in,uid:{}”,uid);

//pk过程中每做一道题返回消息给两个人

int pkId = 0;

if(!“”.equals(jsonObject.getString(“pkId”))){

pkId = Integer.valueOf(jsonObject.getString(“pkId”));

}

if(pkId == 0){

log.info(“challenge pkId is 0”);

return;

}

long usrEntId = -1;

if(!“”.equals(jsonObject.getString(“usrEntId”))){

usrEntId = Long.valueOf(jsonObject.getString(“usrEntId”));

}

if(usrEntId == -1){

log.info(“challenge usrEntId is -1”);

return;

}

int answer = 0;

if(!“”.equals(jsonObject.getString(“answer”))){

answer = Integer.valueOf(jsonObject.getString(“answer”));

}

int time = 0;

if(!“”.equals(jsonObject.getString(“time”))){

time = Integer.valueOf(jsonObject.getString(“time”));

}

int queResId = 0;

if(!“”.equals(jsonObject.getString(“queResId”))){

queResId = Integer.valueOf(jsonObject.getString(“queResId”));

}

int orderNum = 0;

if(!“”.equals(jsonObject.getString(“orderNum”))){

orderNum = Integer.valueOf(jsonObject.getString(“orderNum”));

}

int option = 0;

if(!“”.equals(jsonObject.getString(“option”))){

option = Integer.valueOf(jsonObject.getString(“option”));

}

PkAnswerTime pkAnswerNow = new PkAnswerTime();

pkAnswerNow.setPkGroupId(pkId);

pkAnswerNow.setUsrEntId(usrEntId);

pkAnswerNow.setAnswer(answer);

pkAnswerNow.setTime(time);

pkAnswerNow.setQueResId(queResId);

pkAnswerNow.setOrderNum(orderNum);

pkAnswerNow.setOption(option);

pkMapper.savePkAnswerTime(pkAnswerNow);

PkGroup pkGroup = pkMapper.getPkGroupById(pkId);

if(usrEntId == pkGroup.getInviteUsrEntId()){

long acceptUsrEntId = pkGroup.getAcceptUsrEntId();

judgeWinner(acceptUsrEntId , pkAnswerNow ,client);

}else if(usrEntId == pkGroup.getAcceptUsrEntId()){

long inviteUsrEntId = pkGroup.getInviteUsrEntId();

judgeWinner(inviteUsrEntId , pkAnswerNow ,client);

}

}else if(“again”.equals(action)){

log.info(“again come in”);

//再来一局

int pkId = Integer.valueOf(jsonObject.getString(“pkId”));

log.info(“pkId:”+pkId+“uid:”+uid);

againSendMessage(uid , pkId, client);

}else if(“skill”.equals(action)){

//使用技能

int pkId = Integer.valueOf(jsonObject.getString(“pkId”));

//技能id

int infoId = Integer.valueOf(jsonObject.getString(“info”));

skillSendMessage(uid , pkId , infoId);

}

}

});

socketIOServer.start();

log.info(“socket.io初始化服务完成”);

}

public void stop() {

if (socketIOServer != null) {

socketIOServer.stop();

socketIOServer = null;

}

log.info(“socket.io服务已关闭”);

}

/**

  • 此方法为获取client连接中的参数,可根据需求更改

  • @param client

  • @return

*/

private String getParamsByClient(SocketIOClient client) {

// 从请求的连接中拿出参数(这里的usrEntId必须是唯一标识)

Map<String, List> params = client.getHandshakeData().getUrlParams();

List list = params.get(“usrEntId”);

if (list != null && list.size() > 0) {

return list.get(0);

}

return null;

}

private synchronized void joinSendMessage(long usrEntId , SocketIOClient client , int type , int pkId){

// 给客户端发送一条信息 发送ConnectReceive事件 需要客户端绑定此事件即可接收到消息

JSONObject jsonObject = new JSONObject();

Date date = new Date(new Date().getTime() - 20000);

PkGroup pkGroup = pkMapper.getPkGroupByState(usrEntId , type , date);

if(type != 0 && pkId != 0){

pkGroup = pkMapper.getPkGroupById(pkId);

}

if(type != 0 && pkId == 0){

pkGroup = null;

}

if(pkGroup != null){

pkGroup.setAcceptUsrEntId(usrEntId);

pkGroup.setState(1);

pkMapper.updatePkGroup(pkGroup);

long inviteUsrEntId = pkGroup.getInviteUsrEntId();

WxUserInfo invite = wxUserInfoMapper.queryWxUserInfoByUsrEntId(inviteUsrEntId);

List questions = remyCourseService.listGetRandomTopic(0);

jsonObject.put(“state” , 1);

jsonObject.put(“wxUserInfo” , invite);

jsonObject.put(“questions” , questions);

jsonObject.put(“pkId” , pkGroup.getId());

client.sendEvent(“ConnectReceive”,jsonObject);

SocketIOClient socketIOClient = clientMap.get(inviteUsrEntId);

WxUserInfo accept = wxUserInfoMapper.queryWxUserInfoByUsrEntId(usrEntId);

JSONObject acceptJson = new JSONObject();

acceptJson.put(“state” , 1);

acceptJson.put(“questions” , questions);

acceptJson.put(“pkId” , pkGroup.getId());

acceptJson.put(“wxUserInfo” , accept);

socketIOClient.sendEvent(“ConnectReceive” , acceptJson);

}else{

PkGroup savePkGroup = new PkGroup();

savePkGroup.setInviteUsrEntId(usrEntId);

savePkGroup.setState(0);

savePkGroup.setCreateTime(new Date());

savePkGroup.setType(type);

pkMapper.savePkGroup(savePkGroup);

jsonObject.put(“state” , 0);

jsonObject.put(“pkId” , savePkGroup.getId());

client.sendEvent(“ConnectReceive”,jsonObject);

}

}

private synchronized void botSendMessage(String uid , SocketIOClient client){

JSONObject jsonObject = new JSONObject();

PkGroup pkGroup = pkMapper.getPkGroupByUsrEntIdToAI(Long.valueOf(uid));

if(pkGroup != null){

log.info(“getAI pkGroup is not null come in,uid:{}”,uid);

pkGroup.setAcceptUsrEntId(0l);

pkGroup.setState(1);

pkMapper.updatePkGroup(pkGroup);

List questions = remyCourseService.listGetRandomTopic(0);

jsonObject.put(“state” , 1);

jsonObject.put(“questions” , questions);

jsonObject.put(“pkId” , pkGroup.getId());

client.sendEvent(“AIReceive”,jsonObject);

}

}

private synchronized void judgeWinner(long anotherEntId , PkAnswerTime pkAnswerNow, SocketIOClient client){

log.info(“judgeWinner come in,anotherEntId:{}”,anotherEntId);

int pkId = pkAnswerNow.getPkGroupId();

int orderNum = pkAnswerNow.getOrderNum();

int answer = pkAnswerNow.getAnswer();

int time = pkAnswerNow.getTime();

long usrEntId = pkAnswerNow.getUsrEntId();

int option = pkAnswerNow.getOption();

JSONObject json = new JSONObject();

PkAnswerTime pkAnswerTime = pkMapper.getPkAnswerTimeByParam(anotherEntId , pkId , orderNum);

if(pkAnswerTime != null){

log.info(“judgeWinner pkAnswerTime is not null come in,pkAnswerTime:{}”,pkAnswerTime);

PkGroup pkGroup = pkMapper.getPkGroupById(pkId);

if(orderNum == 5){

pkGroup.setState(2);

pkMapper.updatePkGroup(pkGroup);

}

long winUsrEntId = -1;

if(pkAnswerTime.getAnswer() == 1 && answer == 1){

if(time > pkAnswerTime.getTime()){

winUsrEntId = anotherEntId;

}else if(time < pkAnswerTime.getTime()){

winUsrEntId = usrEntId;

}else{

winUsrEntId = -1;

}

}else if(pkAnswerTime.getAnswer() == 1){

winUsrEntId = anotherEntId;

}else if(answer == 1){

winUsrEntId = usrEntId;

}else{

winUsrEntId = -1;

}

json.put(“winUsrEntId” , winUsrEntId);

json.put(“pkId” , pkId);

json.put(“usrEntId” , anotherEntId);

json.put(“answer” , pkAnswerTime.getAnswer());

json.put(“time” , pkAnswerTime.getTime());

json.put(“option” , pkAnswerTime.getOption());

client.sendEvent(“challengeReceive”,json);

if(anotherEntId != 0){

SocketIOClient socketIOClient = clientMap.get(anotherEntId);

JSONObject acceptJson = new JSONObject();

acceptJson.put(“pkId” , pkId);

acceptJson.put(“usrEntId” , usrEntId);

acceptJson.put(“answer”, answer);

acceptJson.put(“time”, time);

acceptJson.put(“option”,option);

acceptJson.put(“winUsrEntId”,winUsrEntId);

socketIOClient.sendEvent(“challengeReceive” , acceptJson);

}

if(pkGroup.getInviteUsrEntId() == winUsrEntId){

if(pkGroup.getInviteNum() != null){

pkGroup.setInviteNum(pkGroup.getInviteNum() + 1);

}else{

pkGroup.setInviteNum(1);

}

}else if(pkGroup.getAcceptUsrEntId() == winUsrEntId){

if(pkGroup.getAcceptNum() != null){

pkGroup.setAcceptNum(pkGroup.getAcceptNum() + 1);

}else{

pkGroup.setAcceptNum(1);

}

}

pkMapper.updatePkNum(pkGroup);

}

}

private synchronized void againSendMessage(String uid , int pkId , SocketIOClient client){

JSONObject json = new JSONObject();

long usrEntId = Long.valueOf(uid);

PkGroup pkGroup = pkMapper.getPkGroupById(pkId);

log.info(“againSendMessage pkGroup:”+pkGroup);

long opponentId = -1;

if(pkGroup.getAcceptUsrEntId() != null){

if(usrEntId == pkGroup.getAcceptUsrEntId()){

opponentId = pkGroup.getInviteUsrEntId();

}else{

opponentId = pkGroup.getAcceptUsrEntId();

}

}

PkAgainGame pkAgainGame = pkMapper.getPkAgainGame(opponentId , pkId);

log.info(“againSendMessage pkAgainGame:”+pkAgainGame);

if(pkAgainGame == null){

PkAgainGame againGame = new PkAgainGame();

againGame.setCreateTime(new Date());

againGame.setUsrEntId(usrEntId);

againGame.setPkGroupId(pkId);

pkMapper.savePkAgainGame(againGame);

json.put(“usrEntId” , usrEntId);

json.put(“state” , 0);

SocketIOClient socketIOClient = clientMap.get(opponentId);

log.info(“againSendMessage socketIOClient:”+socketIOClient);

socketIOClient.sendEvent(“AgainReceive” , json);

}else{

pkAgainGame.setOpponentUsrEntId(usrEntId);

pkMapper.updatePkAgainGame(pkAgainGame);

//创建房间

PkGroup savePkGroup = new PkGroup();

savePkGroup.setAcceptUsrEntId(usrEntId);

savePkGroup.setInviteUsrEntId(opponentId);

savePkGroup.setState(1);

savePkGroup.setCreateTime(new Date());

savePkGroup.setType(pkGroup.getType());

pkMapper.savePkGroup(savePkGroup);

List questions = remyCourseService.listGetRandomTopic(0);

log.info(“againSendMessage questions:”+questions);

json.put(“state” , 1);

json.put(“questions” , questions);

json.put(“pkId” , savePkGroup.getId());

if(opponentId == 0){

json.put(“wxUserInfo” , “”);

}else{

WxUserInfo invite = wxUserInfoMapper.queryWxUserInfoByUsrEntId(opponentId);

json.put(“wxUserInfo” , invite);

}

client.sendEvent(“AgainReceive”,json);

if(opponentId != 0 && opponentId != -1){

SocketIOClient socketIOClient = clientMap.get(opponentId);

JSONObject acceptJson = new JSONObject();

acceptJson.put(“state” , 1);

acceptJson.put(“questions” , questions);

acceptJson.put(“pkId” , savePkGroup.getId());

WxUserInfo accept = wxUserInfoMapper.queryWxUserInfoByUsrEntId(usrEntId);

acceptJson.put(“wxUserInfo” , accept);

log.info(“againSendMessage socketIOClient:”+socketIOClient);

socketIOClient.sendEvent(“AgainReceive” , acceptJson);

}

}

}

private void skillSendMessage(String uid , int pkId , int infoId){

JSONObject json = new JSONObject();

long usrEntId = Long.valueOf(uid);

PkGroup pkGroup = pkMapper.getPkGroupById(pkId);

log.info(“skillSendMessage pkGroup:”+pkGroup);

long opponentId = -1;

if(usrEntId == pkGroup.getAcceptUsrEntId()){

opponentId = pkGroup.getInviteUsrEntId();

}else{

opponentId = pkGroup.getAcceptUsrEntId();

}

json.put(“usrEntId” , usrEntId);

json.put(“skill” , 1);

json.put(“info” , infoId);

SocketIOClient socketIOClient = clientMap.get(opponentId);

log.info(“skillSendMessage socketIOClient:”+socketIOClient);

socketIOClient.sendEvent(“SkillReceive” , json);

}

}

二、遇到的一些问题

==========

1、最初在发送消息给两人时,有个人能收到消息,有个人收不到
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

独家面经总结,超级精彩

本人面试腾讯,阿里,百度等企业总结下来的面试经历,都是真实的,分享给大家!

image

image

image

image

Java面试准备

准确的说这里又分为两部分:

  1. Java刷题
  2. 算法刷题

Java刷题:此份文档详细记录了千道面试题与详解;

image

image

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!
2934)]

[外链图片转存中…(img-6arXtyqH-1712121432935)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

独家面经总结,超级精彩

本人面试腾讯,阿里,百度等企业总结下来的面试经历,都是真实的,分享给大家!

[外链图片转存中…(img-Njzkyngd-1712121432935)]

[外链图片转存中…(img-o1p0BRSC-1712121432935)]

[外链图片转存中…(img-IMur9unT-1712121432935)]

[外链图片转存中…(img-0poVUf68-1712121432935)]

Java面试准备

准确的说这里又分为两部分:

  1. Java刷题
  2. 算法刷题

Java刷题:此份文档详细记录了千道面试题与详解;

[外链图片转存中…(img-rPvShe5f-1712121432936)]

[外链图片转存中…(img-i1XOomRd-1712121432936)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值