websocket在springboot项目的简单操作

websocket简单上手

1.简介

websocket是一个网络通讯协议,通讯标准是RFC6455

websocket是html5中提供的一种单个tcp连接上进行全双工通讯协议

2.websocket的作用

http协议是无状态,无连接,简单,单项的应用层协议,采用请求响应模式,通信请求只能是客户端主动发起,服务器端进行应答,无法实现服务器端主动向客户端发送消息。

可以使用ajax请求轮询来达到服务器端向客户端发起推送的消息功能,但效率低,资源浪费严重。

基于该背景,websocket技术出现了,该技术允许客户端和服务器端进行全双工通讯,只需要建立一次连接就可以保持连接状态。利用心跳机制实现维护连接状态。

网络中的接收和发送数据都是使用 SOCKET 进行实现。但是如果此套接字已经断开,那发送数据和接收数据的时候就一定会有问题。可是如何判断这个套接字是否还可以使用呢?这个就需要在系统中创建心跳机制。所谓 “心跳” 就是定时发送一个自定义的结构体(心跳包或心跳帧),让对方知道自己 “在线”。以确保链接的有效性。

而所谓的心跳包就是客户端定时发送简单的信息给服务器端告诉它我还在而已。代码就是每隔几分钟发送一个固定信息给服务端,服务端收到后回复一个固定信息,如果服务端几分钟内没有收到客户端信息则视客户端断开。

在 WebSocket 协议中定义了 心跳 Ping心跳 Pong 的控制帧:

  • 心跳 Ping 帧包含的操作码是 0x9。如果收到了一个心跳 Ping 帧,那么终端必须发送一个心跳 Pong 帧作为回应,除非已经收到了一个关闭帧。否则终端应该尽快回复 Pong 帧。
  • 心跳 Pong 帧包含的操作码是 0xA。作为回应发送的 Pong 帧必须完整携带 Ping 帧中传递过来的 “应用数据” 字段。如果终端收到一个 Ping 帧但是没有发送 Pong 帧来回应之前的 Ping 帧,那么终端可以选择仅为最近处理的 Ping 帧发送 Pong 帧。此外,可以自动发送一个 Pong 帧,这用作单向心跳。

3.websocket使用

浏览器和服务器端都必须实现websocket协议建立连接。

3.1websocket客户端

前提:支持html5的浏览器

3.1.1创建客户端websocket对象
//url:指定要连接的url地址,protocol这个参数可选,用于指定可接受的子协议
var Socket=new WebSocket(url,[protocol]);
3.1.2websocket对象中的属性介绍
//制度属性readyState表示的连接状态,其值0表示连接未建立,1表示连接建立,2表示连接正在关闭,3表示连接已关闭或者连接不能开启
Socket.readyState
//只读属性bufferedAmount已被send()放入队列等待传输
Socket.bufferedAmount
3.1.3websocket事件介绍
//建立连接时触发
Socket.onopen
//客户端接受服务端数据时触发
Socket.onmessage
//通讯发生错误时触发
Socket.onerror
//连接关闭时触发
Socket.onclose

3.1.4websocket方法
//发送数据
Socket.send()
//关闭连接
Socket.close()

3.1.5websocket前端简单测试代码
<!DOCTYPE html>  
<meta charset="utf-8" />  
<title>WebSocket Test</title>  
<script language="javascript"type="text/javascript">  
    var wsUri ="ws://127.0.0.1:8080/myWebsocket"; 
    var  websocket = new WebSocket(wsUri); 
    //用来存放创建的多个连接对象 
    var websocketarray=new Array();
    function testWebSocket() { 
        websocket.onopen = function(evt) { 
            onOpen(evt) 
        }; 
        websocket.onmessage = function(evt) { 
            onMessage(evt) 
        }; 
        websocket.onerror = function(evt) { 
            onError(evt) 
        }; 
        websocket.onclose = function(evt) { 
         onClose(evt) 
        }; 
    }  
 
    function onOpen(evt) { 
        writeToScreen("新建连接"); 
    }  
 
    function onClose(evt) { 
      console.log('websocket 断开: ' + evt.code + ' ' + evt.reason + ' ' + evt.wasClean)
      console.log(evt)
        writeToScreen("关闭连接"); 
    }  
 
    function onMessage(evt) { 
        writeToScreen('收到消息'+ evt.data); 
    }  
 
    function onError(evt) { 
        writeToScreen('出现错误 '+ evt.data); 
    }   
 
    function writeToScreen(message) { 
         console.info(message)
    }  
 
    function submit(){
       //new 一个websocket就是新建了一个连接
       websocket = new WebSocket(wsUri);
       websocketarray.push(websocket);
       testWebSocket();
    }
    function stop(){
      //设置从离当前连接最近一次连接删除
      var stopwebsocket=websocketarray.pop();
      //关闭该连接
      stopwebsocket.close()
      //websocketarray.splice(websocketarray.length-1,1);
    }
    function postmessage(){
       var c=document.getElementById("message");
       websocket.send(c.value)
    }
    window.addEventListener("load", testWebSocket, false); 
</script>
<body>
   <h2>WebSocket Test</h2>  
   <button onclick="submit()">启动新的连接</button><br>
   <button onclick="stop()">主动断开连接</button><br>
   <input type="text" id="message" placeholder="写要发送的消息">
   <button onclick="postmessage()">发送消息</button><br>
</body>  
</html>

3.2websocket服务端

这里有很多方案,比如使用Node(Socket.IO,WebSocket-Node),java,python等,我用的Java,在springboot项目中实现。基本使用注解操作

3.2.1springboot导websocket依赖
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
3.2.2配置websocket环境
@Configuration
//开启websocket
@EnableWebSocket
public class MyWebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpoint() {
        return new ServerEndpointExporter();
    }
}
3.2.3创建websocket服务类
//有点类似我们经常用的@RequestMapping。比如你的启动端口是 8080,
// 而这个注解的值是 myWebsocket,那我们就可以通过 ws://127.0.0.1:8080/myWebsocket 来连接你的应用

@ServerEndpoint("/myWebsocket")
@Component
public class MyWebSocketService {

    private  Session session;

    //存放每个客户端对应的MyWebSocket对象,就是一个session客户端对应后台一个mywebsocket服务实例
    //可以这样理解:我的一个session都是具备触发建立连接,关闭连接,发送消息,接受消息的基本功能
    //这些功能的基本实现需要这个服务实例支撑,也就是说客户端服务器端实例是一对一的关系
    private static CopyOnWriteArraySet<MyWebSocketService> webSockets = new CopyOnWriteArraySet<>();

    //连接成功
    //当 websocket 建立连接成功后会触发这个注解修饰的方法,注意它有一个  Session 参数
    @OnOpen
    public void onOpen(Session session) {
        this.session=session;
        System.out.println(session.hashCode());
        webSockets.add(this);
        sendAll("服务器广播消息》》》》》浏览器》》》"+webSockets.size()+"》》》连接成功!!");
        System.out.println("新连接成功"+webSockets.size());
    }

    //连接关闭
    //当 websocket 建立的连接断开后会触发这个注解修饰的方法
    @OnClose
    public void onClose(Session session) {
        for (MyWebSocketService s:webSockets
             ) {
            if(s.session==this.session){
                webSockets.remove(s);
            }
        }
        System.out.println("新连接关闭"+this.session.hashCode());
    }

   //收到消息
    //当客户端发送消息到服务端时,会触发这个注解修改的方法
    @OnMessage
    public String onMsg(String text) throws IOException {
        System.out.println("服务器收到浏览器消息"+text);
        //这个返回的string就是给当前session的浏览器的消息!
        return  "服务器给浏览器发消息"+text;
    }

    //出现异常
    //当 websocket 建立连接时出现异常会触发这个注解修饰的方法
    @OnError
    public void onError(Session session, Throwable throwable) {
        try {
            System.out.println("触发异常");
            session.close();
        } catch (IOException e) {
            System.out.println("发送失败");
            e.printStackTrace();
        }
    }

    //群发消息
    private void sendAll(String message) {
        for (MyWebSocketService myWebSocketService:webSockets) {
            myWebSocketService.session.getAsyncRemote().sendText(message);
        }
    }
}

4.使用websocket测试结果

4.1启动springboot项目,浏览器打开前端测试代码

在这里插入图片描述

到此最简单的websocket算是弄通了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
springboot学习笔记 spring基础 Spring概述 Spring的简史 xml配置 注解配置 java配置 Spring概述 Spring的模块 核心容器CoreContainer Spring-Core Spring-Beans Spring-Context Spring-Context-Support Spring-Expression AOP Spring-AOP Spring-Aspects Messaging Spring-Messaging WEB Spring-Web Spring-Webmvc Spring-WebSocket Spring-Webmvc-Portlet 数据访问/集成(DataAccess/Intefration) Spring-JDBC Spring-TX Spring-ORM Spring-OXM Spring-JMS Spring的生态 Spring Boot Spring XD Spring Cloud Spring Data Spring Integration Spring Batch Spring Security Spring HATEOAS Spring Social Spring AMQP Spring Mobile Spring for Android Spring Web Flow Spring Web Services Spring LDAP Spring Session Spring项目快速搭建 Maven简介 Maven安装 Maven的pom.xml dependencies dependency 变量定义 编译插件 Spring项目的搭建 Spring Tool Suite https://spring.io/tools/sts/all IntelliJ IDEA NetBeans https://netbeans.org/downloads/ Spring基础配置 依赖注入 声明Bean的注解 @Component组件,没有明确的角色 @Service在业务逻辑层(service层) @Repository在数据访问层(dao层) @Controller在展现层(MVC→SpringMVC) 注入Bean的注解 @Autowired:Spring提供的注解 @Inject:JSR-330提供的注解 @Resource:JSR-250提供的注解 Java配置 @Configuration声明当前类是一个配置类 @Bean注解在方法上,声明当前方法的返回值为一个Bean AOP @Aspect 声明是一个切面 拦截规则@After @Before @Around PointCut JoinPoint Spring常用配置 Bean的Scope Singleton Prototype Request Session GlobalSession SpringEL和资源调用 注入普通字符 注入操作系统属性 注入表达式云算结果 注入其他Bean的属性 注入文件内容 注入网址内容 注入属性文件 Bean的初始化和销毁 Java配置方式 注解方式 Profile @Profile 通过设定jvm的spring.profiles.active参数 web项目设置在Servlet的context parameter中 事件Application Event 自定义事件,集成ApplicationEvent 定义事件监听器,实现ApplicationListener 使用容器发布事件 Spring高级话题 Spring Aware BeanNameAware BeanFactoryAware
在Spring Boot中整合WebSocket和Kafka可以实现实时的消息推送和处理。下面是一个简单的步骤: 1. 首先,在Spring Boot项目中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency> ``` 2. 创建一个WebSocket配置类,用于配置WebSocket相关的内容。可以使用@EnableWebSocket注解启用WebSocket,同时实现WebSocketConfigurer接口重写registerWebSocketHandlers方法。在registerWebSocketHandlers方法中,创建一个WebSocketHandler,并使用registerHandler方法将其注册到WebSocketHandlerRegistry中。 ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "/websocket"); } @Bean public WebSocketHandler myHandler() { return new MyHandler(); } } ``` 3. 创建一个WebSocketHandler类,用于处理WebSocket的连接、消息发送和接收等操作。在该类中,可以使用@Autowired注解引入KafkaTemplate实例,以便于在处理消息时发送到Kafka。 ```java @Component public class MyHandler extends TextWebSocketHandler { @Autowired private KafkaTemplate<String, String> kafkaTemplate; @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 处理接收到的消息,并发送到Kafka String payload = message.getPayload(); kafkaTemplate.send("my_topic", payload); } } ``` 4. 创建一个Kafka消息消费者,用于从Kafka中接收消息并发送到WebSocket客户端。可以使用@KafkaListener注解指定监听的主题,并在方法中处理接收到的消息,然后通过WebSocketSession发送到客户端。 ```java @Component public class KafkaConsumer { @Autowired private SimpMessagingTemplate simpMessagingTemplate; @KafkaListener(topics = "my_topic") public void listen(ConsumerRecord<String, String> record) { String message = record.value(); simpMessagingTemplate.convertAndSend("/topic/my_topic", message); } } ``` 以上是整合WebSocket和Kafka的简单示例。你可以根据自己的需求进行扩展和修改。希望对你有所帮助!如果有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值