IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> SpringBoot基于注册实现的Websocket Server端 -> 正文阅读

[网络协议]SpringBoot基于注册实现的Websocket Server端

在线WebSocket客户端工具

Maven依赖

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-http</artifactId>
            <version>5.7.16</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.7.RELEASE</version>
                <configuration>
                    <mainClass>com.hwl.socket.SocketApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
<!--            用于将当前项目当成war包-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.0</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>

四个类 启动类 websocket具体处理类 websocket拦截器类 websocket注册类

启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
//  ws://localhost:5000/websocket?key=A     开发时
//  ws://192.168.110.6:8080/socket/websocket?key=A  部署到tomcat时

@SpringBootApplication
@EnableWebSocket
public class SocketApplication extends SpringBootServletInitializer {

//	使用SpringBoot内置tomcat启动项目的启动方法
	public static void main(String[] args) {
		SpringApplication.run(SocketApplication.class, args);
	}

//	使用外置Tomcat启动项目的棋类方法 继承SpringBootServletInitializer 重写 configure
	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
		return builder.sources(SocketApplication.class);
	}

}

webSocket具体处理类

// Handler 这个类是单例的。交由SpringBoot管理是单例的不交也是单例的
@Slf4j
//@Component    这个类注入也行不注入野心。
public class Handler extends TextWebSocketHandler {

	//静态变量,用来记录当前在线连接数。
	private static final AtomicInteger onlineCount = new AtomicInteger(0);
	//concurrent包的线程安全
	private static final ConcurrentHashMap<String, WebSocketSession> map = new ConcurrentHashMap<String, WebSocketSession>();

//	由于这个类是单例的所以这样写是有问题的。 应用时要另行处理
	private String key;


	//	连接建立成功调用的方法
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		this.key = String.valueOf(session.getAttributes().get("key"));
		addOnlineCount();
		map.put(key, session);
		log.info("[WebSocket] 新的连接加入:{}\t当前有{}个连接", key, getOnlineCount());
	}

	//	收到客户端消息后调用的方法
	@Override
	protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
		log.info("[WebSocket] 来自 {}-{} 的消息:{}", this.hashCode(), key, message);
		try {
			sendMessage(new SimpleDateFormat("yy-MM:dd HH:mm:ss").format(new Date()));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	//	连接关闭调用的方法
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
		map.remove(key);
		subOnlineCount();           //在线数减1
		log.info("[WebSocket] 连接关闭:{}\t当前有{}个连接", key, getOnlineCount());
	}


	/*

	 */
/**
 * 发生错误时调用
 *
 * @param session
 * @param error
 *//*

	@OnError
	public void onError(Session session, Throwable error) {
		log.error("[WebSocket] 异常:{}", error.getMessage());
	}
*/

	/**
	 * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
	 */
	public void sendMessage(String message) throws IOException {
		// 这个处理是有问题的。	key 一直是最后一个连接用户的key. 这个对象是单例的
		map.get(key).sendMessage(new TextMessage(message));
		//this.session.getAsyncRemote().sendText(message);
	}

	public static synchronized int getOnlineCount() {
		return onlineCount.get();
	}

	public static synchronized void addOnlineCount() {
		onlineCount.getAndIncrement();

	}

	public static synchronized void subOnlineCount() {
		onlineCount.getAndDecrement();
	}
}

webSocket拦截器类

import cn.hutool.http.HttpUtil;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.UUID;

@Component
public class HandlerInterceptor implements HandshakeInterceptor {

	@Override   // 握手前
	public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
		Map<String, String> paramMap = HttpUtil.decodeParamMap(request.getURI().getQuery(), StandardCharsets.UTF_8);
		attributes.put("key", paramMap.getOrDefault("key","default")+ UUID.randomUUID().toString().substring(0,5));
		return true;
	}

	@Override   // 握手后
	public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
	                           WebSocketHandler wsHandler, Exception exception) {
	}
}

webSocket注册类

import com.hwl.socket.interceptor.HandlerInterceptor;
import com.hwl.socket.server.Handler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
public class WebSocketRegister implements WebSocketConfigurer {
	@Autowired
	private HandlerInterceptor handlerInterceptor;
//	@Autowired
//	private Handler handler;
	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
		registry.addHandler(new Handler(), "websocket")    # 访问的path
				.addInterceptors(handlerInterceptor)	# 拦截器
				.setAllowedOrigins("*");					# 跨域
	}
}

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-12-11 16:04:59  更:2021-12-11 16:07:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:45:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码