WebSocket通信

1.导入相应的jar包(这里默认使用ssm框架)

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

2.xml配置

    <!--webSocket配置-->
    <websocket:handlers allowed-origins="*">
         <!--配置消息处理器
          handler:这里是消息处理器的id
          path:是指前端与后端建立webSocket连接时要访问的url
       -->
        <websocket:mapping path="/myHandler.do" handler="myHandler"/>
        <!--配置拦截器,在进去消息处理器之前会先来到这个拦截器-->
        <websocket:handshake-interceptors>
             <!--拦截器-->
            <bean class="com.wmzx.view.websocket.WebSocketInterceptor"/>
        </websocket:handshake-interceptors>
    </websocket:handlers>
   <!--配置消息体大小的限制-->
    <bean class="org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean">
        <property name="maxTextMessageBufferSize" value="8192"/>
        <property name="maxBinaryMessageBufferSize" value="8192"/>
    </bean>
 <!--消息处理器-->
    <bean id="myHandler" class="com.wmzx.view.websocket.MyHandler"/>

3.拦截器

package com.wmzx.view.websocket;
import com.common.exception.WMZXException;
import com.common.util.json.APICase;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import java.util.Map;

/**
 * 在webSocket请求过来时,会首先进入这个拦截器,在这里我们可以做授权登录等操作
 */
public class WebSocketInterceptor extends HttpSessionHandshakeInterceptor
{
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
        Map<String, Object> attributes) throws Exception
    {
       //获取shiro的subject
        Subject subject = SecurityUtils.getSubject();
        //校验是否登录
        if (!subject.isRemembered() && !subject.isAuthenticated())
        {
            throw new WMZXException(APICase.NEED_LOGIN);
        }
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }
}

 

4.消息处理器

package com.wmzx.view.websocket;

import com.common.util.Logger;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 *    这里处理消息,可以监听到消息连接的建立,消息请求到来,以及session失效等
 * 
 */
public class MyHandler extends TextWebSocketHandler
{
    /**
     * 这个map的key是用户的id,value是WebSocketSession
     */
    private static volatile ConcurrentHashMap<String, WebSocketSession> map = new ConcurrentHashMap<>();
    /**
     * 消息发送过来后,会来到这里,这里可以根据收到的消息做处理,本方法只是将发
     * 送过来的消息又转发到客户端
     */
    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException
    {
        WebSocketMessage textMessage = new TextMessage(message.getPayload());
        for (WebSocketSession old : map.values())
        {
            old.sendMessage(textMessage);
        }
    }
    
   /**
     *  前端与后端的连接建立好之后会调用这个方法,这里我们可以保存客户端的连接
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws IOException
    {
        String userId = session.getPrincipal().getName();
        if (map.contains(userId))
        {
            session.close();
        }
        map.put(userId, session);
    }
    /**
      *当前端主动关闭连接或者前端浏览器关闭或其他方式导致session失效时,会来到这里
      *在这里我们可以做退出登录
      */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws IOException
    {
        map.remove(session.getPrincipal().getName());
        session.close();
    }
}

5.nginx代理配置(主要指https访问)

WebSocket 和 HTTP 协议不同,但是 WebSocket 中的握手和 HTTP 中的握手兼容,它使用 HTTP 中的 Upgrade 协议头将连接从 HTTP 升级到 WebSocket,当客户端发过来一个 Connection: Upgrade 请求头时,Nginx 是不知道的,所以,当 Nginx 代理服务器拦截到一个客户端发来的 Upgrade 请求时,需要显式来设置 Connection 、 Upgrade 头信息,并使用 101(交换协议)返回响应,在客户端和代理服务器、后端服务器之间建立隧道来支持 WebSocket。

location /websocket {
    proxy_pass http://backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

6.请求地址

  1. http://www.blue-zero.com/WebSocket/ 这是一个在线的WebSocket 测试工具

  2. 如果使用tomcat部署服务,最好使用tomcat8及以上版本

  3. ws和wss协议的区别就如同http和https

  • 服务端使用http访问的服务器:ws://192.168.1.36:8080/myHandler.do

  • 服务端使用https访问的服务器:wss://xxx.xxx.com/myHandler.do

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值