赞
踩
基于springboot框架编写一个WebSocket服务端,并通过简单的html界面模拟客户端验证服务端连接。
1、pom.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <groupId>com.example</groupId>
- <artifactId>demo</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>jar</packaging>
-
- <name>demo</name>
- <description>Demo project for Spring Boot</description>
-
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.0.4.RELEASE</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
-
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <java.version>1.8</java.version>
- </properties>
-
- <dependencies>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-thymeleaf</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-websocket</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
- </project>
2、application.yml
- spring:
- thymeleaf:
- prefix: classpath:/templates/
3、Server端代码
3.1、ServerEndpointExporter
首先要注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint。要注意,如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。
- package com.example.demo.config;
-
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.socket.server.standard.ServerEndpointExporter;
-
- @Configuration
- public class WebSocketConfig {
- @Bean
- public ServerEndpointExporter serverEndpointExporter() {
- return new ServerEndpointExporter();
- }
-
- }
3.2 WebSocketServer
- package com.example.demo.webSocket;
-
-
- import org.springframework.stereotype.Component;
-
- import javax.websocket.*;
- import javax.websocket.server.ServerEndpoint;
-
- @ServerEndpoint("/webSocketServer")
- @Component
- public class WebSocketDemo {
-
-
- @OnOpen
- public void onOpen(Session session) {
- System.out.println("新开启了一个webSocket连接" + session.getId());
- }
-
- @OnMessage
- public String onMessage(String message, Session session) {
- System.out.println("收到客户端发送的信息:"+message);
- System.out.println("当前的sessionId:"+session.getId());
- return "SUCCESS";
- }
-
- @OnClose
- public void onClose(Session session, CloseReason reason) {
- System.out.println("webSocket连接关闭:sessionId:"+session.getId() + "关闭原因是:"+reason.getReasonPhrase() + "code:"+reason.getCloseCode());
- }
-
-
- @OnError
- public void onError(Throwable t) {
- t.printStackTrace();
- }
-
- }
4、前端html界面
- <!DOCTYPE html>
- <html>
-
- <head>
- <meta name="viewport" content="width=device-width" />
- <title>WebSocket 客户端</title>
- </head>
-
- <body>
- <div>
- <input type="button" id="btnConnection" value="连接" />
- <input type="button" id="btnClose" value="关闭" />
- <input type="button" id="btnSend" value="发送" />
- </div>
- <script src="/jquery-3.3.1.js" type="text/javascript" charset="utf-8"></script>
- <script type="text/javascript">
- $(function(){
- var socket;
- if(typeof(WebSocket) == "undefined") {
- alert("您的浏览器不支持WebSocket");
- return;
- }
- $("#btnConnection").click(function() {
- //实现化WebSocket对象,指定要连接的服务器地址与端口
- socket = new WebSocket("ws://localhost:8080/webSocketServer");
- //打开事件
- socket.onopen = function() {
- alert("Socket 已打开");
- //socket.send("这是来自客户端的消息" + location.href + new Date());
- };
- //获得消息事件
- socket.onmessage = function(msg) {
- alert(msg.data);
- };
- //关闭事件
- socket.onclose = function() {
- alert("Socket已关闭");
- };
- //发生了错误事件
- socket.onerror = function() {
- alert("发生了错误");
- }
- });
-
- //发送消息
- $("#btnSend").click(function() {
- socket.send("这是来自客户端的消息" + location.href + new Date());
- });
-
- //关闭
- $("#btnClose").click(function() {
- socket.close();
- });
- });
- </script>
- </body>
-
- </html>
5、跳转界面代码
- package com.example.demo.controller;
-
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.GetMapping;
-
- @Controller
- public class HelloWorldController {
- @GetMapping("/hello")
- public String hello() {
- return "/webSocketDemo";
- }
- }
6、目录结构
7、当需要在websocket服务端注入Service或者Dao进行其他的业务逻辑时,常规注入是会产生空指针异常的。
我们需要在websocket中注入applilcationContext对象,从上下文对象中获取。
方法如下:
7.1 先在main方法启动时将application对象注入到webSocket对象中
- public static void main(String[] args) {
- ConfigurableApplicationContext applicationContext = SpringApplication.run(RangerSocketApplication.class, args);
- GatewayWebSocket.setApplicationContext(applicationContext);
- }
7.2 在webSocket服务端设置注入方法,并基于上下文进行获取
- private static ApplicationContext applicationContext;
-
- public static void setApplicationContext(ApplicationContext context) {
- applicationContext = context;
- }
7.3 在获取时赋值
- private GatewayDao gatewayDao;
-
- if(gatewayDao == null) {
- gatewayDao = applicationContext.getBean(GatewayDao.class);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。