springbootstarterwebsocket +netty

1、服务端 

1)、

2)、pom

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
  <groupId>io.netty</groupId>
  <artifactId>netty-all</artifactId>
  <version>5.0.0.Alpha2</version>
</dependency>

3)、MyWebSocketHandler

public class MyWebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
private static Logger logger=LoggerFactory.getLogger(MyWebSocketHandler.class);
public static ChannelGroup channelGroup=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
public static ConcurrentHashMap<String,Channel> channelMap=new ConcurrentHashMap<>();
 

/由于@Autowired注解注入不进去,所以取巧了
    static IServiceXfzhQz serviceXfzhQz;
    static {
        serviceXfzhQz = SpringUtil.getBean(IServiceXfzhQz.class);
    }

@Override
protected void messageReceived(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame textWebSocketFrame) throws Exception {

}

@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
  Channel incomming=ctx.channel();
  channelGroup.add(ctx.channel());
}

@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
  channelGroup.remove(ctx.channel());
  Collection<Channel> col=channelMap.values();
  while (true==col.contains(ctx.channel())){
    col.remove(ctx.channel());
    logger.info("netty客户端连接删除成功!");
  }
}

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
  logger.info("netty与客户端建立连接,通道开启!");
}

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  TextWebSocketFrame msg2=(TextWebSocketFrame)msg;
  logger.info("netty客户端收到服务器数据:{}",msg2.text());
  String date=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
  message(ctx,msg2.text(),date);
}


public void message(ChannelHandlerContext ctx,String msg,String date){
  try {
    Map<String,Object> resultmap=new HashMap<>();
    resultmap.put("MSGTYPE","DL");
    resultmap.put("USERID","2021");
    resultmap.put("CREATEDATE",date);
    String msgtype=(String)resultmap.get("MSGTYPE");


    if(msg.equals("DL")&&msgtype.equals("DL")){
      Channel channel=ctx.channel();
      channelMap.put((String)resultmap.get("USERID"),channel);
      resultmap.put("sucess",true);
      resultmap.put("message","用户链接绑定成功!");
      channel.writeAndFlush(new TextWebSocketFrame(resultmap.toString()));
      logger.info("netty用户:{}连接绑定成功!",(String)resultmap.get("USERID"));
    }else if(msg.equals("DH")&&msgtype.equals("DL")){
      List<Map<String,Object>> list=new ArrayList<>();
      for(Map<String,Object> map:list){
        String userid=(String)map.get("USERID");
        if(channelMap.containsKey(userid)){
          Channel channel=channelMap.get(userid);
          channel.writeAndFlush(new TextWebSocketFrame(resultmap.toString()));
        }
      }
    }
  }catch (Exception e){
    e.printStackTrace();
  }
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause) throws Exception{
Channel incoming=ctx.channel();
  System.out.println("SimpleChatClient:"+incoming.remoteAddress()+"异常");
  cause.printStackTrace();
  ctx.close();
  }
}

4)、NettyServer

public class NettyServer {
  private static Logger logger=LoggerFactory.getLogger(NettyServer.class);
  private final int port;

  public NettyServer(int port){
    this.port=port;
  }

  public void start() throws InterruptedException {

    EventLoopGroup bossGroup=new NioEventLoopGroup();
    EventLoopGroup group=new NioEventLoopGroup();

    try {
      ServerBootstrap sb=new ServerBootstrap();
      sb.option(ChannelOption.SO_BACKLOG,1024);
      sb.group(group,bossGroup).
      channel(NioServerSocketChannel.class)
      .localAddress(this.port)
      .childHandler(new ChannelInitializer<SocketChannel>() {


    @Override
    protected void initChannel(SocketChannel ch) {
      logger.info("收到新的客户端连接:{}",ch.toString());
      ch.pipeline().addLast(new HttpServerCodec());
      ch.pipeline().addLast(new ChunkedWriteHandler());
      ch.pipeline().addLast(new HttpObjectAggregator(8192));
      ch.pipeline().addLast(new WebSocketServerProtocolHandler("/ws","WebSocket",true,65535*10));
      ch.pipeline().addLast(new MyWebSocketHandler());
    }
  });


  ChannelFuture cf=sb.bind().sync();
  System.out.println(NettyServer.class+" 启动正在监听:"+cf.channel().localAddress());
  cf.channel().closeFuture().sync();
  }finally {
    group.shutdownGracefully().sync();
    bossGroup.shutdownGracefully().sync();
  }
  }

}

5)、

@SpringBootApplication
public class WsnettyApplication extends SpringBootServletInitializer {

  public static void main(String[] args) {
    SpringApplication.run(WsnettyApplication.class, args);
    try {
      new NettyServer(8091).start();
    }catch (Exception e){
      System.out.println("NettyServerError"+e.getMessage());
    }
  }

}

2、客户端

@Controller
public class LoginController {

  @RequestMapping("/login")
  public String login(){
    return "login";
  }

  @RequestMapping("/wstest")
  public String wstest(){
    return "wstest";
  }
}

wstest.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="/css/bootstrap.min.css" rel="stylesheet">


<script type="text/javascript">
  var socket;
  if(!window.WebSocket){
    window.WebSocket=window.MozWebSocket;
  }


  if(window.WebSocket)
  {
    socket=new WebSocket("ws://127.0.0.1:8091/ws");
    socket.onmessage=function (ev) {
    var ta=document.getElementById("responseText");
    ta.value+=ev.data+"\r\n";
    }
    socket.onopen=function (ev) {
      var ta=document.getElementById("responseText");
      ta.value+="Netty-WebSocket服务器 .....连接 \r\n";
    };
    socket.onclose=function (ev) {
      var ta=document.getElementById("responseText");
      ta.value+="Netty-WebSocket服务器 .....关闭 \r\n";
    };
  }
  else{
    alert("您的浏览器不支持WebSocket协议!");
  }

  function send(message) {
    if(!window.WebSocket){return;}
      if(socket.readyState==WebSocket.OPEN){
        socket.send(message);
      }else {
        alert("WebSocket 连接没有建立成功!")
      }
  }


</script>
</head>
<body>
<div class="container">


  <form onsubmit="return false;">
  <div class="form-group">
    <h2 class="col-sm-offset-5">ws test</h2>
  </div>
  <div class="form-group">
    <label class="col-sm-offset-3 col-sm-2 control-label">TEXT</label>
    <div class="col-sm-3">
      <input type="text" class="form-control" id="message"
      name="message" placeholder="请输入用户名" value="这里输入信息"/>
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-offset-5 col-sm-4">
    <button type="button" class="btn btn-default"
    onclick="send(this.form.message.value)" >发送ws信息</button>
    </div>
  </div>
  <div class="form-group">
    <label class="col-sm-offset-3 col-sm-2 control-label">服务端返回的信息</label>
    <div class="col-sm-3">
    <textarea id="responseText" style=" 1024px;height: 300px;"></textarea>
    </div>
  </div>
  </form>
</div>
<script src="/js/jquery.js"></script>
<script src="/js/bootstrap.min.js"></script>
</body>
</html>

 

 

原文地址:https://www.cnblogs.com/smallfa/p/15656299.html