WebSocket 使用


在这里插入图片描述

  新建一个 websocket 模块。

  工程目录。
在这里插入图片描述


// pom.xml

<!--   改为 war 包 -->
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
        </dependency>

<!--        <dependency>-->
<!--            <groupId>javax.servlet</groupId>-->
<!--            <artifactId>jstl</artifactId>-->
<!--        </dependency>-->

        <!--      jsp  -->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>

    </dependencies>

<!--   使用插件启动 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    

// application.yml

server:
  port: 8087

spring:
  application:
    name: openapi-websocket
  mvc:
    view:
      prefix: /
      suffix: .jsp

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8080/eureka/


// index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <h3>消息:</h3>
    <h3 id="message"></h3>

    <script type="text/javascript">

        var websocket = null;

        if ('WebSocket' in window) {
            websocket = new WebSocket("ws://localhost:8087/websocket/123");
        } else {
            alert("当前浏览器不支持 websocket.")
        }

        websocket.onerror = function () {
            setMessageInnerHtml("连接错误")
        }

        websocket.onopen = function () {
            setMessageInnerHtml("连接成功")
        }

        websocket.onmessage = function (event) {
            console.log("进来了");
            setMessageInnerHtml(event.data)
        }

        websocket.onclose = function () {
            setMessageInnerHtml("连接关闭")
        }

        window.onbeforeunload = function () {
            closeWebSocket();
        }

        function setMessageInnerHtml(message) {
            var h3 = document.getElementById("message");
            h3.innerHTML = message;
            if ("111" == message) {
                location.href = "http://www.baidu.com";
            }
        }

    </script>

</body>
</html>


// SocketApplication.java

@SpringBootApplication
@EnableEurekaClient
public class SocketApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(SocketApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {

        return builder.sources(SocketApplication.class);
    }
}


// MyInterceptor.java

@Component
public class MyInterceptor extends HttpSessionHandshakeInterceptor {

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {

        // 地址 最后的 / 后内容为会话唯一标识
        String uri = request.getURI().toString();
        String name = uri.substring(uri.lastIndexOf("/") + 1);

        attributes.put("name", name);

        System.out.println("握手之前。。name: " + name);

        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, @Nullable Exception ex) {
        System.out.println("握手之后。。");
        super.afterHandshake(request, response, wsHandler, ex);
    }

}


// MyHandler.java

@Component
public class MyHandler extends TextWebSocketHandler {

    // 记录所有用户和 session 关系
    private static final Map<String, WebSocketSession> allClients = new ConcurrentHashMap<>();

    // 连接成功
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {

        // 获取拦截器中保存的 name
        String name = (String) session.getAttributes().get("name");

        allClients.put(name, session);
    }

    // 连接关闭
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String name = (String)session.getAttributes().get("name");
        allClients.remove(name);
        super.afterConnectionClosed(session, status);
    }

    // 发送消息
    public static void sendMessage(String name, String message) {

        System.out.println("allClients: " + allClients);

        WebSocketSession webSocketSession = allClients.get(name);
        if (webSocketSession != null && webSocketSession.isOpen()) {
            try {
                webSocketSession.sendMessage(new TextMessage(message));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}


// WebsocketConfig.java

@Configuration
@EnableWebSocket
public class WebsocketConfig implements WebSocketConfigurer {

    @Autowired
    private MyHandler myHandler;

    @Autowired
    private MyInterceptor myInterceptor;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
        
	// //绑定拦截器,设置连接地址,及跨域访问
	        webSocketHandlerRegistry.addHandler(myHandler,"/websocket/*").addInterceptors(myInterceptor).setAllowedOrigins("*");
    }
}


// WebsocketController.java

@RestController
@RequestMapping("/send")
public class WebsocketController {

    @RequestMapping("/message/{name}")
    public void message(@PathVariable("name") String name) {
        System.out.println(name);
        MyHandler.sendMessage(name, "接收到消息.");
    }
}



// 测试。
浏览器打开 http://localhost:8087/,再另页打开 http://localhost:8087/send/message/123

  注意。spring cloud 运行 webapp 下的 jsp 文件,需要改为 war 包,使用插件运行。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值