ssm实现webSocket

ssm实现webSocket

一、引入依赖

	<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-websocket</artifactId>
      <version>5.1.5.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-messaging</artifactId>
      <version>5.1.5.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>7.0</version>
      <scope>provided</scope>
    </dependency>

二、编写websocketController

package com.chuji.controller;

import com.chuji.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: 欧阳锋
 * @Description: websocket 接口
 * @Date: Created in 16:25 2021/3/30
 * @Modified By:
 */
@ServerEndpoint("/websocket/{myWebsocket}")
@Component
@Slf4j
public class WebsocketController {

    //用以下代码替换注释掉的代码,问题解决
    private static UserService userService;
    @Autowired
    public void setPlanmecaScreenService(UserService userService){
        WebsocketController.userService = userService;
    }

    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;

    private static final Logger logger = LoggerFactory.getLogger(WebsocketController.class);

    public static Map<String, List<Session>> clients = new ConcurrentHashMap<String, List<Session>>();

    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
    private static ConcurrentHashMap<String, WebsocketController> webSocketSet = new ConcurrentHashMap<String, WebsocketController>();

    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session WebSocketsession;

    String myWebsocket = "";

    /**
     * 连接建立成功调用的方法
     * @param myWebsocket
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("myWebsocket") String myWebsocket, Session session){
        System.out.println(myWebsocket);
        //接收到发送消息的人员编号
        myWebsocket = myWebsocket;
        this.WebSocketsession = session;
        this.session = session;

        List<Session> sessions = null;
        if(clients.get(myWebsocket) != null){
            sessions = clients.get(myWebsocket);
            sessions.add(session);
        }else{
            sessions = new ArrayList<Session>();
            sessions.add(session);
        }
        clients.put(myWebsocket, sessions);

        //加入map中
        webSocketSet.put(myWebsocket, this);
        addOnlineCount();//在线数加1
        System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
    }

    /**
     * 收到客户端消息时触发
     * @param myWebsocket
     * @param message
     * @return
     */
    @OnMessage
    public void onMessage(@PathParam("myWebsocket") String myWebsocket, String message) {
        System.out.println("来自客户端的消息:" + message);
        sendMessage(myWebsocket,message);
//        return "Got your message ("+ message +").Thanks !";
    }

    /**
     * 异常时触发
     * @param myWebsocket
     * @param throwable
     */
    @OnError
    public void onError(@PathParam("myWebsocket") String myWebsocket, Throwable throwable) {
        logger.info("Websocket Connection Exception:" + myWebsocket);
        logger.info(throwable.getMessage(), throwable);
        clients.remove(myWebsocket);
    }

    /**
     * 关闭连接时触发
     * @param myWebsocket
     */
    @OnClose
    public void onClose(@PathParam("myWebsocket") String myWebsocket) {
        logger.info("Websocket Close Connection:" + myWebsocket);
        subOnlineCount();
        clients.remove(myWebsocket);
    }


    /**
     * 将数据传回客户端
     * 异步的方式
     * @param myWebsocket
     * @param message
     */
    public static void broadcast(String myWebsocket, String message) {
        if (clients.containsKey(myWebsocket)) {
//            clients.get(myWebsocket).getAsyncRemote().sendText(message);
            List<Session> sessions = clients.get(myWebsocket);
            for(Session sess : sessions){
                sess.getAsyncRemote().sendText(message);
            }
        } else {
            throw new NullPointerException("[" + myWebsocket +"]Connection does not exist");
        }
    }

    public static synchronized int getOnlineCount() {
        //返回在线人数
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        //在线人数+1
        WebsocketController.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        //在线人数-1
        WebsocketController.onlineCount--;
    }

    public void sendMessage(String myWebsocket, String message) {
        synchronized(webSocketSet.get(myWebsocket)) {
            //根據手機號查詢用戶信息 並轉成json
//            UserPO user = userService.getUserByPhone(myWebsocket);
//            CommonResponse<UserPO> common = new CommonResponse<UserPO>(ResponseTypeEnums.SUCCESS, null, null, user);
//            String json= JSON.toJSONString(common);

            List<Session> sessions = clients.get(myWebsocket);
            for(Session sess : sessions){
                try {
//                    sess.getBasicRemote().sendText(json);
                    sess.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

三、事实上完成了第二步就能基本连接了,但是如果想要后端发送消息到前端的话,需要调用,所以创建WebSocketService

package com.chuji.service;

/**
 * @Author: 欧阳锋
 * @Description: webSocket service
 * @Date: Created in 10:20 2021/3/31
 * @Modified By:
 */
public interface WebSocketService {

    void sendMessage(String userPhone,String type);

}
package com.chuji.service.impl;

import com.alibaba.fastjson.JSON;
import com.chuji.controller.WebsocketController;
import com.chuji.dao.UserPOMapper;
import com.chuji.model.PO.UserPO;
import com.chuji.service.WebSocketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Author: 欧阳锋
 * @Description: webSocket service
 * @Date: Created in 10:21 2021/3/31
 * @Modified By:
 */
@Service
public class WebSocketServiceImpl implements WebSocketService {

    @Autowired
    private UserPOMapper userPOMapper;

    @Autowired
    private WebsocketController webSocket;

    @Override
    public void sendMessage(String userPhone, String type) {
        //獲取修改後的用戶信息
        UserPO userPO = new UserPO();
        userPO.setUserPhone(userPhone);
        userPO.setUserState((byte)1);

        //像用戶端發送信息
        UserPO user = userPOMapper.getUserLoginByPhone(userPO);

        if("updatePassword".equals(type)){
            user.setUserPwd("updatePassword");
        }else{
            user.setUserPwd("");
        }

        webSocket.onMessage(userPhone, JSON.toJSONString(user));
    }

}

四、通过service调用webSocket

	//調用websocket發送數據到前台
    wsService.sendMessage(userPhone,"updatePassword");

写好之后可以用在线websocket测试进行调试
这样就大功告成!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欧阳锋feng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值