本文由作者“大白菜”分享,个人博客 cmsblogs.cn,即时通讯收录时有较多修订和改动。注意:本系列是给IM初学者的文章,IM老油条们还望海涵,勿喷!
cover-opti.png (10.59 KB, 下载次数: 1314)
下载附件 保存到相册
2 年前 上传
1.png (52.5 KB, 下载次数: 1357)
@ChannelHandler.Sharable public class ClientLogin2Handler extends SimpleChannelInboundHandler<LoginResBean> { //1.构造函数私有化,避免创建实体 private ClientLogin2Handler(){} //2.定义一个静态全局变量 public static ClientLogin2Handler instance=null; //3.获取实体方法 public static ClientLogin2Handler getInstance(){ if(instance==null){ synchronized (ClientLogin2Handler.class){ if(instance==null){ instance=new ClientLogin2Handler(); } } } return instance; } protected void channelRead0( ChannelHandlerContext channelHandlerContext, LoginResBean loginResBean) throws Exception { //具体业务代码,参考之前 } }
@ChannelHandler.Sharable public class ClientMsgHandler extends SimpleChannelInboundHandler<MsgResBean> { //1.构造函数私有化,避免创建实体 private ClientMsgHandler(){} //2.定义一个静态全局变量 public static ClientMsgHandler instance=null; //3.获取实体方法 public static ClientMsgHandler getInstance(){ if(instance==null){ synchronized (ClientMsgHandler.class){ if(instance==null){ instance=new ClientMsgHandler(); } } } return instance; } protected void channelRead0( ChannelHandlerContext channelHandlerContext, MsgResBean msgResBean) throws Exception { //具体业务代码,参考之前 } }
.handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) { //1.拆包器 ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,5,4)); //2.解码器 ch.pipeline().addLast(new MyDecoder()); //3.登录Handler,使用单例获取 ch.pipeline().addLast(ClientLogin2Handler.getInstance()); //4.消息发送Handler,使用单例获取 ch.pipeline().addLast(ClientMsgHandler.getInstance()); //5.编码器 ch.pipeline().addLast(new MyEncoder()); } });
//1.定义一个集合存放数据(真实项目可以存放数据库或者redis缓存),这样数据比较安全。 private List<Map<Integer,String>> datas=new ArrayList<Map<Integer,String>>(); //2.服务端推送消息 private void pushMsg(MsgReqBean bean,Channel channel){ Integer touserid=bean.getTouserid(); Channel c=map.get(touserid); if(c==null){//对方不在线 //2.1存放到list集合 Map<Integer,String> data=new HashMap<Integer, String>(); data.put(touserid,bean.getMsg()); datas.add(data); //2.2.给消息“发送人”响应 MsgResBean res=new MsgResBean(); res.setStatus(1); res.setMsg(touserid+">>>不在线"); channel.writeAndFlush(res); }else{//对方在线 //2.3.给消息“发送人”响应 MsgResBean res=new MsgResBean(); res.setStatus(0); res.setMsg("发送成功); channel.writeAndFlush(res); //2.4.给接收人推送消息 MsgRecBean res=new MsgRecBean(); res.setFromuserid(bean.getFromuserid()); res.setMsg(bean.getMsg()); c.writeAndFlush(res); } }
private void login(LoginReqBean bean, Channel channel){ Channel c=map.get(bean.getUserid()); LoginResBean res=new LoginResBean(); if(c==null){ //1.添加到map map.put(bean.getUserid(),channel); //2.给通道赋值 channel.attr(AttributeKey.valueOf("userid")).set(bean.getUserid()); //3.登录响应 res.setStatus(0); res.setMsg("登录成功"); res.setUserid(bean.getUserid()); channel.writeAndFlush(res); //4.根据user查找是否有尚未推送消息 //思路:根据userid去lists查找....... }else{ res.setStatus(1); res.setMsg("该账户目前在线"); channel.writeAndFlush(res); } }
public class ServerChatGroupHandler extends ChannelInboundHandlerAdapter { //映射关系 private static Map<Integer, Channel> map=new HashMap<Integer, Channel>(); //连接断开,触发该事件 @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { //1.获取Channel Channel channel=ctx.channel(); //2.从map里面,根据Channel找到对应的userid Integer userid=null; for(Map.Entry<Integer, Channel> entry : map.entrySet()){ Integer uid=entry.getKey(); Channel c=entry.getValue(); if(c==channel){ userid=uid; } } //3.如果userid不为空,则需要做以下处理 if(userid!=null){ //3.1.删除映射 map.remove(userid); //3.2.移除标识 ctx.channel().attr(AttributeKey.valueOf("userid")).remove(); } } }
public class ServerChatGroupHandler extends ChannelInboundHandlerAdapter { //映射关系 private static Map<Integer, Channel> map=new HashMap<Integer, Channel>(); //连接断开,触发该事件 @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { //1.获取Channel绑定的userid Object userid=channel.attr(AttributeKey.valueOf("userid")).get(); //2.如果userid不为空 if(userid!=null){ //1.删除映射 map.remove(userid); //2.移除标识 ctx.channel().attr(AttributeKey.valueOf("userid")).remove(); } } }
来源:即时通讯网 - 即时通讯开发者社区!
轻量级开源移动端即时通讯框架。
快速入门 / 性能 / 指南 / 提问
轻量级Web端即时通讯框架。
详细介绍 / 精编源码 / 手册教程
移动端实时音视频框架。
详细介绍 / 性能测试 / 安装体验
基于MobileIMSDK的移动IM系统。
详细介绍 / 产品截图 / 安装体验
一套产品级Web端IM系统。
详细介绍 / 产品截图 / 演示视频
引用此评论
引用:ghodss 发表于 2022-07-27 20:13 8.2写那个那个错误方法,你有实践测试过吗?channelInactive方法内访问AttributeMap会访问不到?
精华主题数超过100个。
连续任职达2年以上的合格正式版主
为论区做出突出贡献的开发者、版主等。
Copyright © 2014-2024 即时通讯网 - 即时通讯开发者社区 / 版本 V4.4
苏州网际时代信息科技有限公司 (苏ICP备16005070号-1)
Processed in 0.109375 second(s), 44 queries , Gzip On.