前端部分代码
//app.js
var stompClient = null;
function setConnected(connected) {
$("#connect").prop("disabled", connected);
$("#disconnect").prop("disabled", !connected);
if (connected) {
$("#conversation").show();
}
else {
$("#conversation").hide();
}
$("#notice").html("");
}
function connect() {
var socket = new SockJS('localhost:8099/endpoint-websocket');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
console.log('Connected: ' + frame);
//订阅群聊消息
stompClient.subscribe('/topic/chat', function (result) {
showContent(JSON.parse(result.body));
});
//订阅在线用户消息
stompClient.subscribe('/topic/onlineUser', function (result) {
showOnlineUser(JSON.parse(result.body));
});
});
}
//断开连接
function disconnect() {
if (stompClient !== null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}
//发送聊天记录
function sendContent() {
stompClient.send("/app/multiple/chat", {}, JSON.stringify({'content': $("#content").val()}));
}
//显示聊天记录
function showContent(body) {
$("#record").append("<tr><td>" + body.content + "</td> <td>"+new Date(body.time).toLocaleTimeString()+"</td></tr>");
}
//显示实时在线用户
function showOnlineUser(body) {
$("#online").html("<tr><td>" + body.content + "</td> <td>"+new Date(body.time).toLocaleTimeString()+"</td></tr>");
}
$(function () {
connect();//自动上线
$("form").on('submit', function (e) {
e.preventDefault();
});
$( "#disconnect" ).click(function(){ disconnect(); });
$( "#send" ).click(function() {
sendContent();
});
});
登录页:
<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<head>
<title>Hello WebSocket</title>
<link href="./css/bootstrap.min.css" rel="stylesheet">
<link href="./css/main.css" rel="stylesheet">
<script src="./js/jquery.min.js"></script>
</head>
<body>
<div id="main-content" class="container">
<div class="row">
<div class="col-md-6">
<form class="form-inline" method='post' action="/login">
<div class="form-group">
<input type="text" name="username" class="form-control" placeholder="用户名">
<input type="password" name="pwd" class="form-control" placeholder="密码">
<input type="submit" class="default" value="登录" />
</div>
</form>
</div>
</div>
</div>
</body>
</html>
聊天页面:
<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<head>
<title>devsq聊天室</title>
<link href="./css/bootstrap.min.css" rel="stylesheet">
<link href="./css/main.css" rel="stylesheet">
<script src="./js/jquery.min.js"></script>
<script src="./js/sockjs.min.js"></script>
<script src="./js/stomp.min.js"></script>
<script src="./js/app.js"></script>
</head>
<body>
<div id="main-content" class="container">
<div class="row">
<div class="col-md-6">
<form class="form-inline">
<div class="form-group">
<label for="connect">建立连接通道:</label>
<button id="connect" class="btn btn-default" type="submit">Connect</button>
<button id="disconnect" class="btn btn-default" type="submit" disabled="disabled">Disconnect
</button>
</div>
</form>
</div>
<div class="col-md-6">
<form class="form-inline">
<div class="form-group">
<input type="text" id="content" class="form-control" placeholder="请输入...">
</div>
<button id="send" class="btn btn-default" type="submit">发送</button>
</form>
</div>
</div>
<div class="row">
<div class="col-md-6">
<table id="conversation" class="table table-striped">
<thead>
<tr>
<th>实时在线用户列表</th>
</tr>
</thead>
<tbody id='online'>
</tbody>
</table>
</div>
<div class="col-md-6">
<table id="conversation" class="table table-striped">
<thead>
<tr>
<th>聊天记录</th>
</tr>
</thead>
<tbody id='record'>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
后端代码
package com.liaoxiang.websocket_demo.controller;
import com.liaoxiang.websocket_demo.model.InMessage;
import com.liaoxiang.websocket_demo.model.User;
import com.liaoxiang.websocket_demo.service.WebSocketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
/**
* @auther Mr.Liao
* @date 2019/3/22 19:02
*/
@Controller
public class ChatRoomController {
@Autowired
private WebSocketService webSocketService;
/**
* 模拟数据库用户数据
*/
public static Map<String, String> userMap = new HashMap<>();
static{
userMap.put("jack", "123");
userMap.put("rose", "123");
userMap.put("tom", "123");
}
/**
* 存储登陆的用户
*/
public static Map<String, User> onlineUser = new HashMap<>();
static {
onlineUser.put("123", new User("admin","123"));
}
/**
* 用户登录
*/
@PostMapping("/login")
public String userLogin(@RequestParam String username,
@RequestParam String pwd,
HttpSession session){
System.out.println("登录的用户信息:"+username+":"+pwd);
String password = userMap.get(username);
if (pwd.equals(password)){
User user = new User(username, pwd);
String sessionId = session.getId();
onlineUser.put(sessionId, user);
return "redirect:/chat.html";
}
return "redirect:/error.html";
}
/**
* 推送在线用户
*/
@Scheduled(fixedRate = 1000)
public void onlineUser(){
webSocketService.sendOnlineUser(onlineUser);
}
/**
* 聊天接口
*/
@MessageMapping("/multiple/chat")
public void topicChat(InMessage inMessage, SimpMessageHeaderAccessor headerAccessor){
String sessionID = headerAccessor.getSessionAttributes().get("sessionID").toString();
User user = onlineUser.get(sessionID);
inMessage.setFrom(user.getUsername());
webSocketService.sendTopicChat(inMessage);
}
}
/**
* 推送在线用户
*/
public void sendOnlineUser(Map<String, User> onlineUser) {
String msg = "";
//获取map中的登陆用户信息,将用户名拼成一个字符串
for (Map.Entry<String, User> entry : onlineUser.entrySet()) {
msg = msg.concat(entry.getValue().getUsername()+" 、 ");
}
messagingTemplate.convertAndSend("/topic/onlineUser",new OutMessage(msg));
}
/**
* 推送消息体
*/
public void sendTopicChat(InMessage inMessage) {
String msg = inMessage.getFrom() + " 发送:" + inMessage.getContent();
messagingTemplate.convertAndSend("/topic/chat",new OutMessage(msg));
}
用户下线在SocketChannelInterceptor拦截器中处理一下
/**
* 断开连接
*/
private void disconnect(String sessionID){
System.out.println("【SocketChannelInterceptor-断开连接】");
ChatRoomController.onlineUser.remove(sessionID);
}