当前位置:   article > 正文

Spring使用WebSocket的两种方法&公共聊天室示例_abstractwebsockethandler

abstractwebsockethandler

目录

1.使用内置的AbstractWebSocketHandler

2.使用websocket-api提供的注解/编程式接口

3.前端实现和测试


以 Spring Boot 2.1.0.RELEASE为例

1.使用内置的AbstractWebSocketHandler

该类是一个抽象类,包含于 org.springframework:spring-websocket 包中

这里引入:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-websocket</artifactId>
  4. <version>2.1.0.RELEASE</version>
  5. </dependency>

即可使用

使用时需要继承该类,根据需要重写相应方法即可

例如:

  1. import org.springframework.web.socket.CloseStatus;
  2. import org.springframework.web.socket.TextMessage;
  3. import org.springframework.web.socket.WebSocketMessage;
  4. import org.springframework.web.socket.WebSocketSession;
  5. import org.springframework.web.socket.handler.AbstractWebSocketHandler;
  6. public class MyWebSocketHandler extends AbstractWebSocketHandler {
  7. @Override
  8. public void afterConnectionEstablished(WebSocketSession session) throws Exception {
  9. System.out.println("Connection established");
  10. }
  11. @Override
  12. public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
  13. System.out.println("收到消息:"+message);
  14. Thread.sleep(2000L);
  15. session.sendMessage(new TextMessage("Hello World!"));
  16. }
  17. @Override
  18. public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
  19. System.out.println("Connection closed");
  20. }
  21. }

 如果是Spring MVC可以在XML中配置端点映射(例如映射到/hello):

  1. <websocket:handlers>
  2. <websocket:mapping path="/hello" handler="socketHandler"/>
  3. </websocket:handlers>
  4. <bean class="MyWebSocketHandler" id="socketHandler"/>

也可以继承 AbstractWebSocketMessageBrokerConfigurer 并重写相应方法配置端点(还需要进行注入)

  1. @Override
  2. public void registerStompEndpoints(StompEndpointRegistry registry) {
  3. registry.addEndpoint("/hello").withSockJS();
  4. }

然后就可以和网页通信了

2.使用websocket-api提供的注解/编程式接口

引入依赖:

  1. <dependency>
  2. <groupId>javax.websocket</groupId>
  3. <artifactId>javax.websocket-api</artifactId>
  4. <version>1.1</version>
  5. <scope>provided</scope>
  6. </dependency>

这里使用注解实现:

  1. import Users;
  2. import org.springframework.stereotype.Component;
  3. import javax.websocket.OnMessage;
  4. import javax.websocket.OnOpen;
  5. import javax.websocket.Session;
  6. import javax.websocket.server.PathParam;
  7. import javax.websocket.server.ServerEndpoint;
  8. import java.io.IOException;
  9. @ServerEndpoint(value = "/chatroom/{userName}")
  10. @Component
  11. public class WebsocketServer {
  12. private Session session;
  13. private static int count=0;
  14. @OnOpen
  15. public void onOpen(Session session, @PathParam("userName")String userName) throws IOException {
  16. this.session=session;
  17. //Users用来存放数据,user是该类的一个静态HashMap变量
  18. if(Users.user.get(userName)==null) {
  19. Users.user.put(userName, this);
  20. count++;
  21. }
  22. session.getBasicRemote().sendText("系统消息:当前在线人数:"+count);
  23. }
  24. @OnMessage
  25. public void onMessage(String msg) throws IOException {
  26. for(WebsocketServer server:Users.user.values()){
  27. server.session.getBasicRemote().sendText(msg);
  28. }
  29. }
  30. }

还需要注入ServerEndpointExporter:

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.socket.server.standard.ServerEndpointExporter;
  4. @Configuration
  5. public class WebSocketConfig {
  6. @Bean
  7. public ServerEndpointExporter confServerEndpointExporter(){
  8. return new ServerEndpointExporter();
  9. }
  10. }

这里有一个大坑,网上的很多案例里面,@ServerEndpoint标记的类,都没有使用@Component,我在测试的时候,总是报404错误,无法连接,加上该注解后问题解决

如果是编程式实现,只要继承 javax.websocket.Endpoint 类并实现/重写相关方法,剩下的和注解式相同

3.前端实现和测试

写了两个简单页面,就不用Controller进行映射了,直接把页面放到 resource/static 下

index.html:

  1. <html>
  2. <head>
  3. <meta charset="UTF-8">
  4. <title>登录</title>
  5. </head>
  6. <body>
  7. <form action="chat.html" method="get">
  8. 你的名字:<input type="text" name="userName"/>
  9. <input type="submit" value="提交"/>
  10. </form>
  11. </body>
  12. </html>

chat.html:

  1. <html>
  2. <head>
  3. <meta charset="UTF-8">
  4. <title>聊天</title>
  5. <script type="text/javascript" src="webjars/jquery/2.1.4/jquery.min.js"></script>
  6. <script type="application/javascript">
  7. var url=null;
  8. var sock=null;
  9. var userName=getQueryString("userName")
  10. //百度来的函数,用来截取参数
  11. function getQueryString(name) {
  12. var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
  13. var r = window.location.search.substr(1).match(reg);
  14. if (r != null) return unescape(r[2]); return null;
  15. }
  16. $(function(){
  17. if(!window.WebSocket){
  18. alert('你的浏览器不支持WebSocket');
  19. }else{
  20. url='ws://localhost:8080/chatroom/'+userName
  21. sock=new WebSocket(url)
  22. sock.onopen=function () {
  23. $("#content").append("<h1>欢迎"+userName+"来到聊天室</h1>");
  24. }
  25. sock.onmessage=function (e) {
  26. $("#content").append("<p>"+e.data+"</p>")
  27. }
  28. sock.onclose=function () {
  29. window.close();
  30. }
  31. }
  32. });
  33. function sendMessage() {
  34. var date=new Date()
  35. sock.send(userName+" "+date.toLocaleTimeString()+" 说<br/>"+$('.msg').val())
  36. $('.msg').val("")
  37. }
  38. </script>
  39. </head>
  40. <body>
  41. <div id="content"></div>
  42. <input type="text" class="msg"/><br/>
  43. <input type="button" value="发送" onclick="sendMessage()"/><br/>
  44. <input type="button" value="关闭websocket" onclick="sock.close()"/>
  45. </body>
  46. </html>

这样就能实现一个公共聊天室了:

如果想实现私聊也很简单,稍作修改就可以,我写了个简单实现:

修改后的chat.html:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>聊天</title>
  6. <script type="text/javascript" src="webjars/jquery/2.1.4/jquery.min.js"></script>
  7. <script type="application/javascript">
  8. var url=null;
  9. var sock=null;
  10. var userName=getQueryString("userName")
  11. function getQueryString(name) {
  12. var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
  13. var r = window.location.search.substr(1).match(reg);
  14. if (r != null) return unescape(r[2]); return null;
  15. }
  16. $(function(){
  17. if(!window.WebSocket){
  18. alert('你的浏览器不支持WebSocket');
  19. }else{
  20. url='ws://localhost:8080/chatroom/'+userName
  21. sock=new WebSocket(url)
  22. sock.onopen=function () {
  23. $("#content").append("<p>欢迎"+userName+"来到聊天室</p>");
  24. }
  25. sock.onmessage=function (e) {
  26. $("#content").append("<p>"+e.data+"</p>")
  27. }
  28. sock.onclose=function () {
  29. window.close();
  30. }
  31. }
  32. });
  33. function sendMessage() {
  34. var date=new Date()
  35. sock.send(userName+" "+date.toLocaleTimeString()+" 说<br/>"+$('.msg').val())
  36. $('.msg').val("")
  37. }
  38. function sendPrivateMessage() {
  39. var date=new Date()
  40. sock.send("<font color='red'>"+userName+date.toLocaleTimeString()+"对"+$('.privatechat').val()+"悄悄说<br/>"+$('.msg').val()+"</font>")
  41. $('.msg').val("")
  42. }
  43. </script>
  44. </head>
  45. <body>
  46. <div id="content"></div>
  47. <input type="text" class="msg"/><br/>
  48. <input type="button" value="发送" onclick="sendMessage()"/><br/>
  49. <input type="button" value="关闭websocket" onclick="sock.close()"/>
  50. 对他私聊:<input type="text" class="privatechat"/><br/>
  51. <input type="button" value="发送私聊" onclick="sendPrivateMessage()"/><br/>
  52. </body>
  53. </html>

主要就是增加了一个私密发送的方法

WebSocketServer类的onMessage方法略作修改即可:

  1. @OnMessage
  2. public void onMessage(String msg) throws IOException {
  3. if(msg.startsWith("<font")){
  4. String user2=msg.substring(msg.indexOf("对")+1,msg.indexOf("悄悄"));
  5. WebsocketServer server2=Users.user.get(user2);
  6. if(server2!=null){
  7. server2.session.getBasicRemote().sendText(msg);
  8. }
  9. session.getBasicRemote().sendText(msg);
  10. }else {
  11. for (WebsocketServer server : Users.user.values()) {
  12. server.session.getBasicRemote().sendText(msg);
  13. }
  14. }
  15. }

效果:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/241965
推荐阅读
相关标签
  

闽ICP备14008679号