netty框架学习之初始篇---多客户端的实现

来源:互联网 发布:mac windows 文件系统 编辑:程序博客网 时间:2024/06/07 15:13

前面基础已经搞定,那么解决问题的重点来了,如何使用netty搭建一个可以识别不同客户端的server?

晚上回来经过一个多小时的奋斗,搞定了这个问题,但是我也不知道我这种方式是否有什么问题或者说方向是否正确,感觉与自己用bio写的socket似乎是一样的道理,简单的地方就是无需关注线程问题。


上代码,

package com.netty.demo2;import java.net.InetAddress;import java.util.HashMap;import java.util.Map;import io.netty.channel.Channel;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;public class HelloServerHandler extends SimpleChannelInboundHandler<String> {static Map<String, Channel> channelMap = new HashMap<String, Channel>();//用于存储客户端id与channel的关系    /**     * 覆盖了 channelRead0() 事件处理方法。每当从服务端读到客户端写入信息时,将信息转发给其他客户端的 Channel。     */    @Override    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {    Channel channel = ctx.channel();    if(msg.equals("111111")||msg.equals("222222")){    channelMap.put(msg,channel);    }        System.out.println(ctx.channel().remoteAddress() + " Say : " + msg);// 收到消息直接打印输出        byte [] b = {0x01,0x02};        if(msg.equals("123")){        channelMap.get("222222").writeAndFlush("发送给123的信息");        }else if(msg.equals("456")){        channelMap.get("111111").writeAndFlush("发送给456的信息");}    }    /**     *      * 覆盖 channelActive 方法 在channel被启用的时候触发 (在建立连接的时候)     *      * channelActive 和 channelInActive 在后面的内容中讲述,这里先不做详细的描述     * */    @Override    public void channelActive(ChannelHandlerContext ctx) throws Exception {        System.out.println("RamoteAddress : " + ctx.channel().remoteAddress() + " active !");        ctx.writeAndFlush( "Welcome to " + InetAddress.getLocalHost().getHostName() + " service!\n");        super.channelActive(ctx);    }    }



这个是HelloServerHandler 的完整版,首先继承SimpleChannelInboundHandler类并覆盖其中的几个方法,代码中写的很详细,各个方法的作用就不再赘述。


详细的讲一下流程和几个细节问题,

流程:client连接到server时,首先发送一个注册id到server,比如A客户端发送“111111”这样的字符串表示其id,B客户端发送“222222”,当A连接到server发送其注册id时将其与channel存储到channelMap中,当B连接到server的时候做同样处理。此时就有两个客户端连接到了server了,那么让A发送“123”字符串,当server收到后将其发送给B。如何发送给B呢,当A发送123的时候,channelRead0方法中的channel时A的channel而不是B的,于是我们首先要拿到B的channel才能调用writer方法给B发消息,那么此时就要调用map的get方法,获取map中的channel,于是这样路就通了。

结果:


客户端使用的一个软件模拟的,这个软件可以多开,省去了写客户端的麻烦,回头上传。

细节:

此处的Map必须静态化,不然是没法存储不同的channel的。

channelMap用来存储客户端id与channel的对应关系,所谓的客户端id就是客户端的注册名称。


下一步与数据库整合,并实现后台管理(不知道是用struts2还是servlet或者spring mvc,,,选择综合症)

有时间再研究下websocket是如何实现的。。。


小弟菜鸟,有不对的地方望大神指正,另外这种区分客户端的方式如果有更简便、更高效,更牛逼的方式希望童鞋们能教导一下


爱编程,爱学习,爱挑战。

程序猿就是我,我就是程序猿。


0 0
原创粉丝点击