SpringBoot + mybatis-plus整合webscoket

webscoket原理:请参考WebSocket的实现原理
webscoket一开始我只是简单会用,但是我觉得掌握webscoket原理是很有必要,他会加深我们对计网的理解。

一、永恒第一步:导入pom依赖
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
   <groupId>org.webjars</groupId>
   <artifactId>stomp-websocket</artifactId>
   <version>2.3.3</version>
</dependency>
二、添加配置文件

对应部分的说明都写在了注释里面

package com.easy.config;

import com.mbyte.easy.webscoket.consts.GlobalConsts;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

/**
 * @Author zte
 * @Description Webscoket配置类
 * @Date 21:33 2019/5/6
 **/
@Configuration
@EnableWebSocketMessageBroker
@EnableCaching
@CrossOrigin("*")
public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {
   
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
   
        /**
         * 配置消息代理
         * 启动简单Broker,消息的发送的地址符合配置的前缀来的消息才发送到这个broker
         */
        config.enableSimpleBroker(GlobalConsts.TOPICPATH, GlobalConsts.P2PPUSHBASEPATH);
        config.setUserDestinationPrefix(GlobalConsts.P2PPUSHBASEPATH);
        config.setApplicationDestinationPrefixes(GlobalConsts.APP_PREFIX);
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
   
        /**
         * 注册 Stomp的端点
         * addEndpoint:添加STOMP协议的端点。这个HTTP URL是供WebSocket或SockJS客户端访问的地址
         * setAllowedOrigins("*") 允许跨域
         * withSockJS:指定端点使用SockJS协议
         */
        registry.addEndpoint(GlobalConsts.ENDPOINT)
                .setAllowedOrigins("*")
                .withSockJS();
    }
}

如果需要跨域,则需要添加跨域设置

package com.easy.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

import javax.annotation.Resource;

/**
 * @className: WebSocketConfig
 * @description:
 * @author: zte
 * @create: 2020-06-09 16:17
 **/
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
   


    @Resource
    private MyHandShakeInterceptor handshake;

    @Resource
    private MyHandler handler;

    /**
     * 实现 WebSocketConfigurer 接口,重写 registerWebSocketHandlers 方法,这是一个核心实现方法,配置 websocket 入口,允许访问的域、注册 Handler、SockJs 支持和拦截器。
     * <p>
     * registry.addHandler()注册和路由的功能,当客户端发起 websocket 连接,把 /path 交给对应的 handler 处理,而不实现具体的业务逻辑,可以理解为收集和任务分发中心。
     * <p>
     * addInterceptors,顾名思义就是为 handler 添加拦截器,可以在调用 handler 前后加入我们自己的逻辑代码。
     * <p>
     * setAllowedOrigins(String[] domains),允许指定的域名或 IP (含端口号)建立长连接,如果只允许自家域名访问,这里轻松设置。如果不限时使用”*”号,如果指定了域名,则必须要以 http 或 https 开头。
     *
     */
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
   
        //部分 支持websocket 的访问链接,允许跨域
        registry.addHandler(handler, "/websocket").addInterceptors(handshake).setAllowedOrigins("*");
        //部分 不支持websocket的访问链接,允许跨域
//        registry.addHandler(handler, "/sockjs/echo").addInterceptors(handshake).setAllowedOrigins("*").withSockJS();
    }
}
三、WebScoket常量配置
package com.easy.webscoket.consts;

/**
 * @program: easy
 * @description: WebScoket常量配置
 * @author: zte
 * @create: 2019-05-06 10:11
 **/
public class GlobalConsts {
   
    public static final String TOPIC = "/topic/greetings";

    public static final String ENDPOINT = "/gs-guide-websocket";

    public static final String APP_PREFIX = "/app";

    public static final String HELLO_MAPPING = "/hello";

    //点对点消息推送地址前缀
    public static final String P2PPUSHBASEPATH = "/user";
    //点对点消息推送地址后缀,最后的地址为/user/用户识别码/msg
    public static final String P2PPUSHPATH = "/msg";


    /**
     * @Description 接收消息地址
     **/
    public static final String RECEIVE_MAPPING = "/receive";



    /**
     * @Description 订阅消息推送地址前缀
     **/
    public static final String TOPICPATH = "/group";

    /**
     * 统一前缀
     */
    public static final String URL_PREFIX = "/rest/";

}

四、controller层代码

这里包含了点对点聊天以及群聊的配置

package com.easy.webscoket.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mbyte.easy.common.web.AjaxResult;
import com.mbyte.easy.detailed_info_log.entity.DetailedInfoLog;
import com.mbyte.easy.talk_socket.entity.Message;
import com.mbyte.easy.talk_socket.service.IMessageService;
import com.mbyte.easy.webscoket.consts.GlobalConsts;
import com.mbyte.easy.webscoket.vo.ClientMessage;
import com.mbyte.easy.webscoket.vo.ServerMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.util.HtmlUtils;

import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import java.awt.event.MouseWheelEvent;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @program: easy
 * @description: webscoket测试controller
 * @author: zte
 * @create: 2019-05-06 10:26
 **/
@Controller
@RequestMapping("/audience/index")
public class GreetingController {
   

    @Autowired
    private SimpMessagingTemplate template;

    @Autowired
    private IMessageService messageService;

    /**
     * 在线用户的Map集合,key:用户名,value:Session对象
     */
    private static Map<String, Session> sessionMap = new ConcurrentHashMap<>();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("username") String username) {
   
        //在webSocketMap新增上线用户
        sessionMap.put(username, session);

        System.out.println(username);

    }


    @RequestMapping
    public String index(Model model) {
   

        return "webscoket/greeting";
    }

    @RequestMapping("/index2")
    public String index2(Model model) {
   

        return "webscoket/greeting2";
    }

    @MessageMapping(GlobalConsts.HELLO_MAPPING)
    @SendTo(GlobalConsts.TOPIC)
    public ServerMessage greeting(ClientMessage message) throws Exception {
   
        // 模拟延时,以便测试客户端是否在异步工作
//        Thread.sleep(1000);
        template.convertAndSendToUser(message.getId() + "", GlobalConsts.P2PPUSHPATH, JSON.toJSON(new ServerMessage("Hello, " + HtmlUtils.htmlEscape(message.getName()
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值