首页 > 其他分享 >websocket介绍

websocket介绍

时间:2023-05-01 22:55:21浏览次数:27  
标签:websocket ctx 介绍 ws new public channel 客户端

特点:
1.可以在浏览器里使用
2.支持双向通信
3.使用简单
全双工异步通信,tcp协议服用http握手通道
优点:
1.双向通信,实时性更强。
2.更好的二进制支持
3.较少的控制开销。连接创建后,ws客户端、服务端进行数据交换时,协议控制的数据包头部较小。在不包含头部的情况下,服务端到客户端的包头只有2~10字节(取决于数据包长度),客户端到服务端的的话,需要加上额外的4字节的掩码。而HTTP协议每次通信都需要携带完整的头部。
了解知识点:
a.建立连接 b.交换数据 c.数据帧格式 d.如何维持连接
支持方式:
1.java端作为服务端
2.另起前端作为服务端

 

java作为服务端时:

 

/**
 * 初始化器:
 */
public class NettyServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline pipeline= socketChannel.pipeline();
        //以下三个是Http的支持
        //http解码器
        pipeline.addLast(new HttpServerCodec());
        //支持写大数据流
        pipeline.addLast(new ChunkedWriteHandler());
        //http聚合器
        pipeline.addLast(new HttpObjectAggregator(1024*62));
        //websocket支持,设置路由
        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
        //添加自定义的助手类
        pipeline.addLast(new NettyHandler());
    }
}

 

package com.example.demo.netty.nettyprogram;

import com.alibaba.fastjson.JSON;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * 自定义助手类:
 * 这个类就是业务的核心,客户端的请求会在这里处理。
 * 比如客户端连接、客户端发送消息、给客户端发送消息等等。
 * 自定义助手类需要重写的方法可以根据自己的需求重写,
 * 这里就不把每个方法都重写一遍了,完整的大家可以去找找文档看看。
 */
public class NettyHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    //TextWebSocketFrame是netty用于处理websocket发来的文本对象
    //所有正在连接的channel都会存在这里面,所以也可以间接代表在线的客户端
    public static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    //在线人数
    public static int online;
    //接收到客户都发送的消息
    @Override
    public void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        final String text = msg.text();//客户端发送的文本信息,可以根据需要转换成send_message
        Send_Message send_message=new Send_Message();
        SendAllMessages(ctx,send_message);//send_message是我的自定义类型,前后端分离往往需要统一数据格式,可以先把对象转成json字符串再发送给客户端
    }
    //客户端建立连接
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        channelGroup.add(ctx.channel());
        online=channelGroup.size();
        System.out.println(ctx.channel().remoteAddress()+"上线了!");
    }
    //关闭连接
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        channelGroup.remove(ctx.channel());
        online=channelGroup.size();
        System.out.println(ctx.channel().remoteAddress()+"断开连接");
    }

    //出现异常
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
    }

    //给某个人发送消息
    private void SendMessage(ChannelHandlerContext ctx, Send_Message msg) {
        ctx.channel().writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(msg)));
    }

    //给每个人发送消息,除发消息人外
    private void SendAllMessages(ChannelHandlerContext ctx,Send_Message msg) {
        for(Channel channel:channelGroup){
            if(!channel.id().asLongText().equals(ctx.channel().id().asLongText())){
                channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(msg)));
            }
        }
    }
}

 

public class NettyServer {
    private static int port;

    public NettyServer(int port) {
        this.port = port;
    }
    public static void start() throws InterruptedException {//在main方法里调用这个方法,并用构造函数设置端口号
        //创建主线程组,接收请求
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //创建从线程组,处理主线程组分配下来的io操作
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        //创建netty服务器
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup)//设置主从线程组
                    .channel(NioServerSocketChannel.class)//设置通道
                    .childHandler(new NettyServerInitializer());//子处理器,用于处理workerGroup中的操作
            //启动server
            ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
            //监听关闭channel
            channelFuture.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();//关闭主线程
            workerGroup.shutdownGracefully();//关闭从线程
        }
    }
}

 

另起的前端作为服务端:WebSocket服务端
服务端用了ws这个库。相比大家熟悉的socket.io,ws实现更轻量

var app = require('express')();
var server = require('http').Server(app);
var WebSocket = require('ws');

var wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', function connection(ws) {
    console.log('server: receive connection.');
    
    ws.on('message', function incoming(message) {
        console.log('server: received: %s', message);
    });

    ws.send('world');
});

app.get('/', function (req, res) {
  res.sendfile(__dirname + '/index.html');
});

app.listen(3000);

 

 

客户端:向8080端口发起WebSocket连接。连接建立后,打印日志,同时向服务端发送消息。接收到来自服务端的消息后
<script>
  var ws = new WebSocket('ws://localhost:8080');
  ws.onopen = function () {
    console.log('ws onopen');
    ws.send('from client: hello');
  };
  ws.onmessage = function (e) {
    console.log('ws onmessage');
    console.log('from server: ' + e.data);
  };
</script>

 

标签:websocket,ctx,介绍,ws,new,public,channel,客户端
From: https://www.cnblogs.com/wangbiaohistory/p/17367145.html

相关文章

  • 1.Docker的介绍与安装
    1.Docker的介绍与安装 1.1什么是Docker​Docker是基于Go语言实现的云开源项目。  Docker的主要目标是Build,ShipandRunAnyApp,Anywhere,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够......
  • 1.Docker的介绍与安装
    1.Docker的介绍与安装 1.1什么是Docker​Docker是基于Go语言实现的云开源项目。  Docker的主要目标是Build,ShipandRunAnyApp,Anywhere,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够......
  • JSX语法介绍
    title:02-JSX语法介绍publish:trueJSX介绍JSX的引入如果直接让用户通过JS代码手动创建DOM元素,肯定是非常麻烦的。于是,React官方就提出了一套JSX语法规范,能够让我们在JS文件中,书写类似于HTML那样的代码,快速定义虚拟DOM结构。JSX的全称JSX:JavaScriptXML,一种类......
  • React介绍
    title:01-React介绍publish:true虚拟DOM和diff算法在学习React之前,我们需要先了解两个概念:虚拟DOM、diff算法。虚拟DOM问题描述:假设我们的数据发生一点点的变化,也会被强制重建整颗DOM树,这么做,会涉及到很多元素的重绘和重排,导致性能浪费严重。解决上述问题的思路:实......
  • LSTM和双向LSTM介绍
    (一)RNN的长期依赖问题循环神经网络RNN在训练的过程中会有长期依赖的问题,这是由于RNN模型在训练时会遇到梯度消失(大部分情况)或者梯度爆炸(很少,但对优化过程影响很大)的问题。对于梯度爆炸是很好解决的,可以使用梯度修剪(GradientClipping),即当梯度向量大于某个阈值,缩放梯度向量......
  • BI中外挂插件之 TabularEditor 介绍
    此前,我们说过了PowerBI将在今年夏天内置支持至少三大外挂插件,如下:  在PowerBIDesktop没有正式发布这些集成前,各大插件要准备好被集成。本文来说说其中的 空手造车 插件,名叫:TabularEditor。下载与安装在它没有被内置到PowerBI前,大家可以自由下载使用。该插件是开......
  • mysql几个主流版本介绍
    MySQL是一款非常流行的关系型数据库管理系统,历经多个版本。以下是MySQL的主流版本:MySQL5.7:该版本于2013年发布,包含了许多新特性和改进,如更好的性能、JSON支持、多源复制等。MySQL8.0:该版本于2018年发布,引入了原生JSON支持、更好地Unicode支持、解决云端部署时结构化数据需......
  • android2.3新增API StrictMode介绍
    google在android2.3中新增了StrictModeAPI来设置对一个thread的策略(ui线程或者分线程),它主要检测了读写操作,访问网络,数据库读写等耗时的操作并将其以log或者dialog等形式打印出来。分析这些日志,我们可以尽快找出程序运行缓慢的原因进而优化代码,避免ANR(ApplicationNotRespondin......
  • 可见光遥感目标检测(一)任务概要介绍
    前言 本篇开始对遥感图像的目标检测进行介绍,介绍了其目标前景、数据集以及评价指标。本教程禁止转载。同时,本教程来自知识星球【CV技术指南】更多技术教程,可加入星球学习。欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结、最新技术跟踪、经典论文解读、CV招聘信息。CV各......
  • 吴恩达Prompt课 - 01 介绍
    吴恩达和OpenAI一起制作了节一个半小时的,面向开发者的关于《ChatGPTPromptEngineering》的课,对自己Prompt提高非常有帮助。英文课程地址:https://www.deeplearning.ai/short-courses/chatgpt-prompt-engineering-for-developers/我反复学习后,针对每小节的例子和关键部分按......