还是和上几篇一样,先给出前面笔记的连接,有没看的可以去看看再来!

netty01   、 netty02  、netty03

看到这里、你基本上可以使用netty接受信息和根据对应的信息返回信息了


接下来我们在web项目中使用,通过访问去启动,通过请求去给指定的客户端发信息,所以说到这篇就是重点了,我们不讲底层,不讲理论,直接上代码!

因为自己就是从零开始的,一上来你就给我讲一大堆理论、底层、我就mmp哦!了解底层我个人觉得你总是得会基本的使用了然后再开始去理解底层吧,不然那么枯燥无味的事情,谁会喜欢?

那我们就接着上一篇的来哈!

  1. package com.netty.nettys01;
  2. import com.service.NettyTest01;
  3. import io.netty.buffer.ByteBuf;
  4. import io.netty.buffer.Unpooled;
  5. import io.netty.channel.Channel;
  6. import io.netty.channel.ChannelHandlerContext;
  7. import io.netty.channel.ChannelId;
  8. import io.netty.channel.ChannelInboundHandlerAdapter;
  9. import io.netty.channel.group.ChannelGroup;
  10. import io.netty.channel.group.DefaultChannelGroup;
  11. import io.netty.util.concurrent.GlobalEventExecutor;
  12. import java.util.HashMap;
  13. import java.util.Iterator;
  14. import java.util.Map;
  15.  
  16. import static org.apache.http.Consts.UTF_8;
  17.  
  18. public class DiscardServerHandler extends ChannelInboundHandlerAdapter {
  19. /**
  20. * 在这里使用DefaultChannelGroup将每次连接的 Channel 存起来,每一个Channel 底层就是一个连接
  21. */
  22. private static final ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
  23. private static final Map map = new HashMap<String,ChannelId>();
  24. @Override
  25. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  26. /**
  27. * 这里就是添加了
  28. */
  29. channels.add(ctx.channel());
  30. /**
  31. * 获取每一个连接的唯一标示吧,相当于
  32. */
  33. ChannelId Id= ctx.channel().id();
  34. /**
  35. * map就不用解释了吧,这里就用 1 代替了key;正常项目的话肯定使用用户的唯一标示了
  36. */
  37. map.put("1",Id);
  38. /**
  39. * 这里只是写了个测试遍历了一下
  40. */
  41. Iterator<Channel> ls= channels.iterator();
  42. while (ls.hasNext()){
  43. Channel l= ls.next();
  44. System.out.println(l.id().toString());
  45. }
  46.  
  47. }
  48.  
  49. /**
  50. * 下面这两个get方法是个人使用方法,不好的还希望大家给点意见
  51. * @return
  52. */
  53. public static ChannelGroup getChannels() {
  54. return channels;
  55. }
  56. public static Map getMap() {
  57. return map;
  58. }
  59.  
  60. @Override
  61. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  62. ByteBuf in=(ByteBuf)msg;
  63. System.out.println(ctx.channel().id().toString()+"收到信息:"+in.toString(UTF_8));
  64.  
  65. String reMsg="66666";
  66. ByteBuf in2= Unpooled.copiedBuffer(reMsg.getBytes());
  67. ctx.writeAndFlush(in2);
  68. new NettyTest01().test(null,null);
  69.  
  70. }
  71.  
  72. @Override
  73. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  74. cause.printStackTrace();
  75. ctx.close();
  76. }
  77. }

对于上面的代码,虽然有注释了。不过我还是说一下大概思路吧

  1. channelActive 这个方法会在每次有连接进来的时候执行!
  1. DefaultChannelGroup 这个对象可以用来存储连接,其实我觉得用其他的存也可以哈,不过既然netty本身提供了,我想应该有它自己的优势吧
  2.  
  3. 最后使用一个map存下了登录的唯一标示;虽然key写死了为 1;也就是每次登录会覆盖上一个;这里就只模拟指定发给最后一个登录的客户端了,保存的方式有很多,基于每个项目架构的不同,我也就不多说了!

  1. 下面是发信息的类
  1. package com.service;
  2.  
  3. import com.netty.nettys01.DiscardServerHandler;
  4. import io.netty.buffer.Unpooled;
  5. import io.netty.channel.Channel;
  6. import io.netty.channel.ChannelId;
  7. import io.netty.channel.group.ChannelGroup;
  8. import org.springframework.stereotype.Service;
  9.  
  10. import java.util.Iterator;
  11. import java.util.Map;
  12.  
  13. @Service
  14. public class NettyTest01 {
  15.  
  16. public void test(ChannelId id,String key){
  17. /**
  18. * 每次调用获取所有的连接;
  19. */
  20. ChannelGroup channelGroup=DiscardServerHandler.getChannels();
  21. Map<String,ChannelId> map= DiscardServerHandler.getMap();
  22. if (key!=null){
  23. ChannelId id2= map.get("1");
  24. Channel el= channelGroup.find(id2);
  25. el.writeAndFlush(Unpooled.copiedBuffer("99999".getBytes()));
  26. return;
  27. }
  28.  
  29. Iterator<Channel> ls= channelGroup .iterator();
  30. while (ls.hasNext()){
  31. Channel l= ls.next();
  32. System.out.println(l.id().toString());
  33. l.writeAndFlush(Unpooled.copiedBuffer("1234545".getBytes()));
  34. }
  35.  
  36. }
  37.  
  38. }

接着说这个类的思路吧,这个类写在service层,交由spring管理了;自然就可以注入到你想注入的地方了!

调用方法判断是否传入key,如果不传入就群发,传入了就发给指定的,当然这里的规则就是你们自己定了

就是根据对应的key获取对应的连接,然后发送信息

下面的是controller 层 的访问启动服务代码,随意写个案例,我就随便放代码了(*╹▽╹*)

  1. package com.controller;
  2. import com.netty.nettys01.DiscardServer;
  3. import com.service.NettyTest01;
  4. import com.service.TestService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  7. import org.springframework.stereotype.Controller;
  8. import org.springframework.web.bind.annotation.RequestMapping;
  9. import org.springframework.web.bind.annotation.ResponseBody;
  10.  
  11. @Controller
  12. public class Controller01 {
  13. @Autowired
  14. private TestService testService;
  15. @Autowired
  16. private NettyTest01 nettyTest01;
  17.  
  18. @Autowired
  19. private ThreadPoolTaskExecutor threadPoolTaskExecutor;
  20.  
  21. @RequestMapping("test2")
  22. public String test02() throws Exception {
  23.  
  24. System.out.println(123);
  25.  
  26. int c= threadPoolTaskExecutor.getActiveCount();
  27. System.out.println("c="+c);
  28. nettyTest01.test(null,"1");
  29. return "index";
  30. }
  31.  
  32. @RequestMapping("test4")
  33. @ResponseBody
  34. public String test04() throws Exception {
  35. new Thread(new Runnable() {
  36. public void run() {
  37. int port;
  38. /* if (args.length > 0) {
  39. port = Integer.parseInt(args[0]);
  40. } else {
  41. port = 8080;
  42. }*/
  43. port = 8089;
  44. try {
  45. new DiscardServer(port).run();
  46. }catch (Exception e){
  47. System.out.println(123);
  48. }
  49.  
  50. }
  51. }).start();
  52.  
  53. return "1";
  54. }
  55.  
  56. @RequestMapping("test3")
  57. @ResponseBody
  58. public int test03(){
  59. System.out.println(123);
  60.  
  61. /* for(int i=0;i<100;i++){
  62. threadPoolTaskExecutor.execute(new Runnable() {
  63. public void run() {
  64. synchronized (Controller01.class) {
  65. try {
  66. String i= HttpUtils.get("http://192.168.31.223:8085/test4.do");
  67. System.out.println(i);
  68. System.out.println(System.currentTimeMillis());
  69. } catch (Exception e) {
  70. e.printStackTrace();
  71. }
  72. }
  73. }
  74.  
  75. });
  76.  
  77. }*/
  78. return testService.get();
  79. }
  80. }
  1. 说一下这个类吧,test4 请求是用来启动的,由于本身启动是堵塞的,所以使用线程启动。。。。。。
    test2 是收到请求以后会给key1的连接发送信息
    回到上面的方法 可以看出 是给最后一个连接发送了信息 99999 这个就是指定的发了
    如果传入两个 null ,就会群发了。。。这篇先说到这里 ,。。。因为我也还在学习。。。。。
  2.  
  3. 可以在连接的时候将对应的id传于客户端,让客户端将id和用户id发回来保存,这样就可以根据用户id获取连接id

netty04(重点来了、指定某个客户端发信息或者群发)小声嘀咕~~我也是从零开始学得、、、想学习netty的又不知道怎么下手的童鞋们~~的更多相关文章

  1. socket 服务器向指定的客户端发消息

    一.需求 需求如题. 当多个客户端连接服务器时,服务器如何给指定的客户端发送消息. 二.解决方案 核心思想: 在服务器端,需保存不同客户端的socket列表及客户端相关信息. socket含有发送方和 ...

  2. (转)openfire插件开发(三)通过http方式向openfire客户端发信息

    转:http://blog.csdn.net/hzaccp3/article/details/19964655 需求:  通过http方式,向openfire客户端发信息(非XMPP协议)openfi ...

  3. 6-51单片机ESP8266学习-AT指令(8266TCP服务器--做自己的AndroidTCP客户端发信息给单片机控制小灯的亮灭)

    http://www.cnblogs.com/yangfengwu/p/8776712.html 先把源码和资料链接放到这里 链接: https://pan.baidu.com/s/1jpHZjW_7 ...

  4. 7-51单片机ESP8266学习-AT指令(8266TCP服务器,编写自己的C#TCP客户端发信息给单片机控制小灯的亮灭)

    http://www.cnblogs.com/yangfengwu/p/8780182.html 自己都是现做现写,如果想知道最终实现的功能,请看最后 先把源码和资料链接放到这里 链接: https: ...

  5. node.js中express模块创建服务器和http模块客户端发请求

    首先下载express模块,命令行输入 npm install express 1.node.js中express模块创建服务端 在js代码同文件位置新建一个文件夹(www_root),里面存放网页文 ...

  6. filter过滤器 默认情况下只对客户端发来的请求有过滤作用 对服务端的跳转不起作用 需要显示的在xml定义过滤的方式才行

    filter过滤器 默认情况下只对客户端发来的请求有过滤作用 对服务端的跳转不起作用 需要显示的在xml定义过滤的方式才行

  7. socket(tcp)互发信息

    一:有图有真相,很简单 a, b, Thread 构造函数(ParameterizedThreadStart)初始化 Thread 类的新实例,指定允许对象在线程启动时传递给线程的委托. 参数star ...

  8. 循序渐进Socket网络编程(多客户端、信息共享、文件传输)

    循序渐进Socket网络编程(多客户端.信息共享.文件传输) 前言:在最近一个即将结束的项目中使用到了Socket编程,用于调用另一系统进行处理并返回数据.故把Socket的基础知识总结梳理一遍. 1 ...

  9. 利用python itchat给女朋友定时发信息

    利用itchat给女朋友定时发信息 涉及到的技术有itchat,redis,mysql,最主要的还是mysql咯,当然咯,这么多东西,我就只介绍我代码需要用到的,其他的,如果需要了解的话,就需要看参考 ...

随机推荐

  1. SQL Server循环

    1.普通循环 DECLARE @i int BEGIN WHERE Uid=@i --PRINT @i END 2.游标循环(没有事务) ---游标循环(没有事务) BEGIN DECLARE @a ...

  2. YCSB之HBase性能测试

    1.YCSB背景 YCSB,全称为“Yahoo!Cloud Serving Benchmark”,是雅虎开发的用来对云服务进行基础测试的工具,其内部涵盖了常见的NoSQL数据库产品,如Cassandr ...

  3. python 基础 列表

    1.列表list()方法用于将元组转换为列表,[]组成,中间可以放很多内容,每一项使用逗号隔开,列表中可以放置任何数据类型的数据.注:元组与列表是非常类似的,区别在于元组的元素值不能修改,元组是放括号 ...

  4. 从外部设置传入Go变量

    前提:必须在build/run时指定 -ldflags="-X main.a=2.0 -X main.b=1" , 且a,b必须是string的变量,不能是常量, 不能是struc ...

  5. 解决KafKa数据存储与顺序一致性保证

    “严格的顺序消费”有多么困难 下面就从3个方面来分析一下,对于一个消息中间件来说,”严格的顺序消费”有多么困难,或者说不可能. 发送端 发送端不能异步发送,异步发送在发送失败的情况下,就没办法保证消息 ...

  6. Poco::Crypto--加解密_RSA

    Poco::Crypto--加解密(RSA) 1.简单的加解密 Cipher::Ptr pCipher = CipherFactory::defaultFactory().createCipher(R ...

  7. 金九银十中,看看这31道Android面试题

    阅读目录 1.如何对 Android 应用进行性能分析 2.什么情况下会导致内存泄露 3.如何避免 OOM 异常 4.Android 中如何捕获未捕获的异常 5.ANR 是什么?怎样避免和解决 ANR ...

  8. VMware虚拟机安装Linux系统centos7(一)

    1.安装虚拟机(自行百度) 2.编辑虚拟机设置 光驱设置,镜像选择:(也可设置2核2G,基于自己计算机选择!) 3.点击开启此虚拟机(上下键选择安装,回车) 4.选择语言 5.设置 如果想安装图形化界 ...

  9. vue.js----之router详解(一)

    在vue1.0版本的超链接标签还是原来的a标签,链接地址由v-link属性控制 而vue2.0版本里超链接标签由a标签被替换成了router-link标签,但最终在页面还是会被渲染成a标签的 至于为什 ...

  10. day 28 面向对象 三种特性之一 多态 鸭子类型 反射(反省)

    多态是OOP的三大特征之一 字面意思:多种形态 多种状态 官方描述:不同的对象可以响应(调用)同一个方法 产生不同的结果(例如水的三相特征) 多态不是什么新技术 我们编写面向对象的程序时 其实就有多态 ...