2019.6.19 springboot之websocket

本文参考相关博客,介绍了使用Spring Boot搭建简易聊天室的步骤。包括加入依赖、编写控制层及公用类、编写主启动类并加入注解和申明类,还提到启动应用后用在线工具测试,过程中遇到拦截器拦截请求问题并解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文参考自:

https://blog.lqdev.cn/2018/08/14/springboot/chapter-nineteen/

搭建一个简易聊天室

0.加入POM依赖。

1
2
3
4
5
6
7
8
<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>

 

1.编写控制层,对应WebSocket的各事件。同时抽取了个公用类,进行通用方法调用。

WebSocketController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
 * websocket 简易聊天
 * @author oKong
 *
 */
//由于是websocket 所以原本是@RestController的http形式 
//直接替换成@ServerEndpoint即可,作用是一样的 就是指定一个地址
//表示定义一个websocket的Server端
@Component
@ServerEndpoint(value = "/my-chat/{usernick}")
@Slf4j
public class WebSocketController {
	
	/**
	 * 连接事件 加入注解
	 * @param session
	 */
	@OnOpen
	public void onOpen(@PathParam(value = "usernick") String userNick,Session session) {
		String message = "有新游客[" + userNick + "]加入聊天室!";
		log.info(message);
		WebSocketUtil.addSession(userNick, session);	
		//此时可向所有的在线通知 某某某登录了聊天室			
		WebSocketUtil.sendMessageForAll(message);
	}
	
	@OnClose
	public void onClose(@PathParam(value = "usernick") String userNick,Session session) {
		String message = "游客[" + userNick + "]退出聊天室!";
		log.info(message);
		WebSocketUtil.remoteSession(userNick);	
		//此时可向所有的在线通知 某某某登录了聊天室			
		WebSocketUtil.sendMessageForAll(message);
	}
	
	@OnMessage
	public void OnMessage(@PathParam(value = "usernick") String userNick, String message) {
		//类似群发
		String info = "游客[" + userNick + "]:" + message;
		log.info(info);
		WebSocketUtil.sendMessageForAll(message);
	} 
	
	@OnError
	public void onError(Session session, Throwable throwable) {
		log.error("异常:", throwable);
		try {
			session.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		throwable.printStackTrace();
	}

}

WebSocketUtil.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class WebSocketUtil {

	/**
	 * 简单使用map进行存储在线的session
	 * 
	 */
    private static final Map<String, Session> ONLINE_SESSION = new ConcurrentHashMap<>();
    
    public static void addSession(String userNick,Session session) {
    	//putIfAbsent 添加键—值对的时候,先判断该键值对是否已经存在
    	//不存在:新增,并返回null
    	//存在:不覆盖,直接返回已存在的值
//    	ONLINE_SESSION.putIfAbsent(userNick, session);
    	//简单示例 不考虑复杂情况。。怎么简单怎么来了。。
    	ONLINE_SESSION.put(userNick, session);
    }
    
    public static void remoteSession(String userNick) {
    	ONLINE_SESSION.remove(userNick);
    }
    
    /**
     * 向某个用户发送消息
     * @param session 某一用户的session对象
     * @param message
     */
    public static void sendMessage(Session session, String message) {
    	if(session == null) {
    		return;
    	}
    	// getAsyncRemote()和getBasicRemote()异步与同步
    	Async async = session.getAsyncRemote();
    	//发送消息
    	async.sendText(message);
    }
    
    /**
     * 向所有在线人发送消息
     * @param message
     */
    public static void sendMessageForAll(String message) {
    	//jdk8 新方法
    	ONLINE_SESSION.forEach((sessionId, session) -> sendMessage(session, message));
    }
}

注意点:

  1. @ServerEndpoint的value值填写时,开头需要加上/,不然会提示路径无效。
  2. 需要加上类型@Component注解,使得能被扫描到。
  3. 这里的session等,都在包javax.websocket包下的,注意区分。

2.编写主启动类,主要是加入注解@EnableWebSocket和申明一个Websocket endpoint类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@SpringBootApplication
@EnableWebSocket
@Slf4j
public class Chapter19Application {

	public static void main(String[] args) {
		SpringApplication.run(Chapter19Application.class, args);
		log.info("Chapter19启动!");
	}
	
	/**
	 * 会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
	 * 要注意,如果使用独立的servlet容器,
	 * 而不是直接使用springboot的内置容器,
	 * 就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。
	 */
	@Bean
	public ServerEndpointExporter serverEndpointExporter() {
		return new ServerEndpointExporter();
	}
}

3.启动应用,利用在线的测试工具进行测试。这里直接使用了http://coolaf.com/tool/chattest进行测试。当然也可以自己写一个html了。

首先,输入我们的服务地址:ws://127.0.0.1:8080/my-chat/okong,(127.0.0.1代表本机)

这里我报错了

 发现是写的拦截器拦截了请求,修改拦截器

成功!

再开一个 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值