springboot -- 整合websocket 实现在线聊天


websocket 实现在线聊天效果

pom.xml

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.53</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

添加 config 配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

后端接收处理消息

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Slf4j
@Controller
public class WebSocketController {

    @RequestMapping("/webSocket/{name}")
    public String webSocket(@PathVariable String name, Model model) {
        try {
            log.info("跳转到websocket的页面上");
            model.addAttribute("username", name);
            return "_user";
        } catch (Exception e) {
            log.info("跳转到websocket的页面上发生异常,异常信息是:" + e.getMessage());
            return "error";
        }
    }

    @RequestMapping("/webSocket")
    public String page() {
        try {
            log.info("跳转到总页面上");
            return "ChatRoom";
        } catch (Exception e) {
            log.info("跳转到websocket的页面上发生异常,异常信息是:" + e.getMessage());
            return "error";
        }
    }
}

Socket处理

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
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.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Component
@ServerEndpoint("/webSocket/{username}")
public class WebSocket {

public static int onlineNumber = 0;
/**
 * 以用户的姓名为key,WebSocket为对象保存起来
 */
private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>();
/**
 * 会话
 */
private Session session;
/**
 * 用户名称
 */
private String username;


@OnOpen
public void onOpen(@PathParam("username") String username, Session session) {
    onlineNumber++;
    log.info("现在来连接的客户id:" + session.getId() + "用户名:" + username);
    this.username = username;
    this.session = session;
    log.info("有新连接加入! 当前在线人数" + onlineNumber);
    try {
        //messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息
        //先给所有人发送通知,说我上线了
        Map<String, Object> map1 = new HashMap<>();
        map1.put("messageType", 1);
        map1.put("username", username);
        sendMessageAll(JSON.toJSONString(map1), username);

        //把自己的信息加入到map当中去
        clients.put(username, this);
        //给自己发一条消息:告诉自己现在都有谁在线
        Map<String, Object> map2 = new HashMap<>();
        map2.put("messageType", 3);
        //移除掉自己
        Set<String> set = clients.keySet();
        map2.put("onlineUsers", set);
        sendMessageTo(JSON.toJSONString(map2), username);
    } catch (IOException e) {
        log.info(username + "上线的时候通知所有人发生了错误");
    }


}

@OnError
public void onError(Session session, Throwable error) {
    log.info("服务端发生了错误" + error.getMessage());
    //error.printStackTrace();
}

@OnClose
public void onClose() {
    onlineNumber--;
    //webSockets.remove(this);
    clients.remove(username);
    try {
        //messageType 1代表上线 2代表下线 3代表在线名单  4代表普通消息
        Map<String, Object> map1 = new HashMap<>();
        map1.put("messageType", 2);
        map1.put("onlineUsers", clients.keySet());
        map1.put("username", username);
        sendMessageAll(JSON.toJSONString(map1), username);
    } catch (IOException e) {
        log.info(username + "下线的时候通知所有人发生了错误");
    }
    log.info("有连接关闭! 当前在线人数" + onlineNumber);
}


@OnMessage
public void onMessage(String message, Session session) {
    try {
        log.info("来自客户端消息:" + message + "客户端的id是:" + session.getId());
        JSONObject jsonObject = JSON.parseObject(message);
        String textMessage = jsonObject.getString("message");
        String fromusername = jsonObject.getString("username");
        String tousername = jsonObject.getString("to");
        //如果不是发给所有,那么就发给某一个人
        //messageType 1代表上线 2代表下线 3代表在线名单  4代表普通消息
        Map<String, Object> map1 = new HashMap<>();
        map1.put("messageType", 4);
        map1.put("textMessage", textMessage);
        map1.put("fromusername", fromusername);
        if (tousername.equals("All")) {
            map1.put("tousername", "所有人");
            sendMessageAll(JSON.toJSONString(map1), fromusername);
        } else {
            map1.put("tousername", tousername);
            sendMessageTo(JSON.toJSONString(map1), tousername);
        }
    } catch (Exception e) {
        log.info("发生了错误了");
    }
}

public void sendMessageTo(String message, String ToUserName) throws IOException {
    for (WebSocket item : clients.values()) {
        if (item.username.equals(ToUserName)) {
            item.session.getAsyncRemote().sendText(message);
            break;
        }
    }
}

public void sendMessageAll(String message, String FromUserName) throws IOException {
    for (WebSocket item : clients.values()) {
        item.session.getAsyncRemote().sendText(message);
    }
}

public static synchronized int getOnlineCount() {
    return onlineNumber;
}

}


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM