增加一个队列,多线程产生的消息都先入队急求顶packagecom.tcp.mina.main;importjava.util.ArrayList;importjava.util.Collection;importjava.util.List;importjava.util.Map;importorg.apache.mina.core.IoUtil;importorg.apache.mina.core.service.IoHandlerAdapter;importorg.apache.mina.core.session.IdleStatus;importorg.apache.mina.core.session.IoSession;importcom.safe.model.Police;importcom.safe.model.User;importcom.safe.service.CenterService;importcom.safe.util.ConstantUtil;importcom.safe.util.DateUtil;importcom.tcp.mina.frame.Frame;importcom.tcp.mina.model.M_p_HandingAlarm;importcom.tcp.mina.model.M_p_Pant;importcom.tcp.mina.model.M_p_PeopleInfo;importcom.tcp.mina.model.M_q_GetPeopleInfo;importcom.tcp.mina.model.M_q_HandingAlarm;importcom.tcp.mina.model.M_q_Pant;importcom.tcp.mina.model.PoliceTask;importcom.tcp.mina.msgcoder.MsgCoder;importcom.tcp.mina.thread.AllPoliceCoordsThread;importcom.tcp.mina.thread.HotPoliceCoordsThread;importcom.tcp.mina.thread.UserCoordsThread;importcom.tcp.mina.util.TCPConstant;publicclassMyServerHandlerextendsIoHandlerAdapter{publicstaticMapallIoSessions;CenterServiceservice;publicMyServerHandler(CenterServiceservice){super();this.service=service;}@OverridepublicvoidexceptionCaught(IoSessionsession,Throwablecause)throwsException{System.out.println("exceptionCaught");cause.printStackTrace();}@OverridepublicvoidmessageReceived(IoSessionsession,Objectmessage)throwsException{System.out.println("【server】messageReceived:"+message);Frameframe=null;if(messageinstanceofFrame){frame=(Frame)message;}else{return;}intmsgType=frame.getMsgType();switch(msgType){/*一收到心跳/caseTCPConstant.MSGTYPE_Q_PANT:M_q_Pantm_q_Pant=newMsgCoder().readFrame(frame,M_q_Pant.class);System.out.println("请求消息-心跳请求:"+m_q_Pant);//响应心跳M_p_Pantp_Pant=newM_p_Pant();session.write(newMsgCoder().readMsg(p_Pant));break;/*二获取人物信息请求/caseTCPConstant.MSGTYPE_Q_PEOPLEINFO:M_q_GetPeopleInfoq_GetPeopleMsg=newMsgCoder().readFrame(frame,M_q_GetPeopleInfo.class);intpeopleType=q_GetPeopleMsg.getType();if(TCPConstant.PEOPLETYPE_POLICE==peopleType){//警员Policepolice=service.getPoliceByPoliceNo(q_GetPeopleMsg.getID().trim());StringbirthdayStr=DateUtil.fmtDateToStr(police.getDetails().getBirthday(),"yyyy-MM-dd");FramepoliceFrame=newMsgCoder().readMsg(newM_p_PeopleInfo(police.getPoliceNo(),peopleType,police.getDetails().getName(),birthdayStr,police.getDetails().getTel(),police.getDetails().getAddress(),police.getDetails().getShenFenId(),police.getDetails().getPhoto()));session.write(policeFrame);}elseif(TCPConstant.PEOPLETYPE_USER==peopleType){//用户Useruser=service.getUserByLoginName(q_GetPeopleMsg.getID().trim());StringbirthdayStr=DateUtil.fmtDateToStr(user.getDetails().getBirthday(),"yyyy-MM-dd");FrameuserFrame=newMsgCoder().readMsg(newM_p_PeopleInfo(user.getLoginName(),peopleType,user.getDetails().getName(),birthdayStr,user.getDetails().getTel(),user.getDetails().getAddress(),user.getDetails().getShenFenId(),user.getDetails().getPhoto()));session.write(userFrame);}break;/*三处理报警请求/caseTCPConstant.MSGTYPE_Q_HANDINGALARM://解析请求消息M_q_HandingAlarmq_handingMsg=newMsgCoder().readFrame(frame,M_q_HandingAlarm.class);//操作派警intalarmId=q_handingMsg.getEventID();inttype=q_handingMsg.getType();if(type==ConstantUtil.ALARM_TYPE_TRUE){//真警则派发任务//派发任务ListpoliceTasks=q_handingMsg.getTask();ListpoliceNos=newArrayList();StringtaskContent="";for(PoliceTaskpoliceTask:policeTasks){policeNos.add(policeTask.getPoliceID());taskContent=policeTask.getTaskInfo();}service.sendTaskAndNotice(policeNos,taskContent,alarmId);}else{//不是真警则修改对应类型1假警2重复报警//修改报警类别service.updateAlarmStatus(alarmId,type);}/*响应该报警的最新状态///发送处理报警的响应消息1这里直接返回给所有客户端,2警员提交任务时发送给所有客户端//AlarmInfoalarmInfo=service.getAlarmById();//TODO假数据M_p_HandingAlarmmsg=newM_p_HandingAlarm(alarmId,2);FramepMsgframe=newMsgCoder().readMsg(msg);//获取所有正在连接的IoSessionCollectionsessions=session.getService().getManagedSessions().values();//将消息写到所有IoSessionIoUtil.broadcast(pMsgframe,sessions);break;default:System.out.println("TCP:TCPListenRequest未知的请求!~");break;}//session.write(message);}@OverridepublicvoidmessageSent(IoSessionsession,Objectmessage)throwsException{System.out.println("【server】messageSent:"+message);}@OverridepublicvoidsessionClosed(IoSessionsession)throwsException{System.out.println("【server】sessionClosed");System.out.println("有人关闭,当前客户数:"+allIoSessions.size());}@OverridepublicvoidsessionCreated(IoSessionsession)throwsException{System.out.println("【server】sessionCreated");}@OverridepublicvoidsessionIdle(IoSessionsession,IdleStatusstatus)throwsException{System.out.println("【server】sessionIdle");}@OverridepublicvoidsessionOpened(IoSessionsession)throwsException{System.out.println("【server】sessionOpenedID:"+session.getId());if(allIoSessions==null){allIoSessions=session.getService().getManagedSessions();}System.out.println("有人连接,当前客户数:"+allIoSessions.size());newThread(newAllPoliceCoordsThread(session,service)).start();newThread(newHotPoliceCoordsThread(session,service)).start();newThread(newUserCoordsThread(session,service)).start();}}
handler的完整代码。结果很惨,同时在多个线程里收发消息就会出现消息错乱了
session加同步试试呗...
不负责的建议回复@颖辉小居:那三个线程难道不是你写的?直接锁住IoSession这个对象不就行了回复@maradona:如果是我自己的方法我加个锁没问题,可是发送消息的IOSession是引用包里的。获得它的地方是通过重写别人的方法,得到的回复@颖辉小居:你都用多线程了...不知道怎么同步?IOSession没说是线程安全的吧..这个同步锁怎么加啊?发出消息都是session直接调用的write
时隔一年再看这个问题感触良多
packageyh.net.mina;importorg.apache.mina.core.session.IoSession;publicclassIoSender{publicstaticvoidnoticeMsg(IoSessionsession,Objectmsg){synchronized(session){session.write(msg);}}}
这样应该可以吧!
为了解决服务端主动持续的多线程的向同一个Iosession(客户端)发送消息