本文章是使用Springboot+WebSocket简单实现一个web界面的聊天室
项目结构如下
- 首先在springboot项目的pom.xml中导入所需要的依赖包web、websocket以及解析JSON格式的fastjson
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies>
2.实现前端登录界面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="GBK">
<title>Title</title>
<script src="js/jquery-3.4.1.min.js"></script>
<!-- 将boostrap的css导入进来-->
<link rel="stylesheet" type="text/css" href="js/boostrap/css/bootstrap.css">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<style>
*{
padding: 0;
margin: 0;
}
.wrap{
width: 500px;
height: 400px;
position: relative;
top: 70px;
border: 1px dodgerblue solid;
border-radius: 10px;
margin: 0 auto;
}
.head{
background-color: #2b669a;
color: white;
text-align: center;
border-radius: 10px 10px 0 0;
}
h1{
padding: 30px;
margin: 0px;
}
.body{
padding: 50px;
background-color: white;
}
html,body {
height: 100%;
}
#btn{
margin-left: 100px;
}
body {
height: 100%;
/* for IE */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=white, endColorstr=lightblue);
/* for other Browser */
background-image: linear-gradient(bottom, lightblue 0%, white 100%);
background-image: -o-linear-gradient(bottom, lightblue 0%, white 100%);
background-image: -moz-linear-gradient(bottom, lightblue 0%, white 100%);
background-image: -webkit-linear-gradient(bottom, lightblue 0%, white 100%);
background-image: -ms-linear-gradient(bottom, lightblue 0%, white 100%);
}
#btn3{
padding: 10px;
border-radius: 5px;
background: #01aaed;
}
/*当屏幕大小小于768的时候*/
@media screen and (max-width: 768px) {
.wrap{
width: 100% !important;
height: 100% !important;
top: 0;
background-color: white;
}
h1{
font-size: 20px !important;
}
.form-group{
margin: 20px;
}
}
</style>
</head>
<body>
<div class="wrap">
<div class="head"><h1>欢迎使用V2.0聊天室</h1></div>
<div class="body">
<from id="form">
<div class="form-group"><label>账号: </label><input id="username" class="form-control" name="username"></div>
<div class="form-group"><label>密码: </label><input id="password" class="form-control" name="password"></div>
<div id="btn" class="form-group">
<button type="button" onclick="ajaxdl()" id="btn3" class="btn btn-primary">登录</button>
</div>
</from>
</div>
</div>
<script>
function ajaxdl(){
$.ajax({
url:"login",
data: {
username:document.getElementById("username").value,
password:document.getElementById("password").value
},
success:function (res){
if (res == '1'){
window.location.href="ws.html"
}else{
alert("密码错误")
}
}
})
}
</script>
<script>
</script>
</body>
</html>
3.校验账密,并将将用户登录状态存储到session中
@RestController
public class LoginController {
@RequestMapping("/login")
public String login(HttpServletRequest request){
String username = request.getParameter("username");
String password = request.getParameter("password");
if (password.equals("123")){
request.getSession().setAttribute("user",username);
return "1";
}else{
return "登录失败";
}
}
}
4.进入聊天室界面
4.1身份校验后,建立websocket连接,接收消息
<script>
var ws;
jQuery.ajax({
url:"check",
success(res){
if (res == 'SUCCESS'){
alert("你还没有登录,请先去登录!")
window.location.href="boostrap.html"
}else{
var name = document.getElementById("user-name");
name.innerHTML = res;
var user = res;
//建立websocket连接
if ('WebSocket' in window) {
ws = new WebSocket("ws://localhost:8080/ws?loginuser="+user);
} else if ('MozWebSocket' in window) {
ws = new MozWebSocket("ws://localhost:8080/ws?loginuser="+user);
} else {
console.log('Error: WebSocket is not supported by this browser.');
return;
}
}
//实现接收消息的事件-+
ws.onmessage=function(res){
var msg = JSON.parse(res.data);
if (msg.code == 1){
$("#listcontent").append("<div>"+msg.message+"</div>");
//更新聊天列表
$("#userlist").empty();
for (var i = 0; i < msg.data.length; i++) {
$("#userlist").append("<div>"+msg.data[i]+"</div>");
}
//更新在线人数
var lab = document.getElementById("lab");
lab.innerHTML = msg.data.length;
}else if(msg.code == 2){
$("#listcontent").append("<div>"+msg.message+"</div>");
}else if(msg.code == 3){
$("#listcontent").append("<div>"+msg.message+"</div>");
}
}
}
})
</script>
4.2前端聊天室界面代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="GBK">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<script src="js/jquery-3.4.1.min.js"></script>
<style>
.content{
position: relative;
height: 400px;
width: 380px;
border: black 5px solid;
border-radius: 20px;
overflow-y: auto;
display: inline-block;
}
@media screen and (max-width: 768px) {
}
#userlist{
display: inline-block;
height: 150px;
width: 50px;
border: black 1px solid;
overflow-y: auto;
float: right;
}
.hhh{
position: relative;
left: 200px;
margin: 0;
padding: 0;
}
h1{
margin: 0;
padding: 0;
display: inline-block;
}
#msg{
border: 2px solid black;
border-radius: 4px;
}
#userlist{
border-color:#01aaed;
}
.btn1{
padding: 10px;
border-radius: 5px;
background: #01aaed;
}
.btn2{
padding: 10px;
border-radius: 5px;
background: #01aaed;
}
</style>
</head>
<body>
<h1>聊天室V3.0</h1>
<div class="hhh"><h5>在线人数: <label id="lab"></label></h5></div>
<script>
var ws;
jQuery.ajax({
url:"check",
success(res){
if (res == 'SUCCESS'){
alert("你还没有登录,请先去登录!")
window.location.href="boostrap.html"
}else{
var name = document.getElementById("user-name");
name.innerHTML = res;
var user = res;
//建立websocket连接
if ('WebSocket' in window) {
ws = new WebSocket("ws://localhost:8080/ws?loginuser="+user);
} else if ('MozWebSocket' in window) {
ws = new MozWebSocket("ws://localhost:8080/ws?loginuser="+user);
} else {
console.log('Error: WebSocket is not supported by this browser.');
return;
}
}
//实现接收消息的事件-+
ws.onmessage=function(res){
var msg = JSON.parse(res.data);
if (msg.code == 1){
$("#listcontent").append("<div>"+msg.message+"</div>");
//更新聊天列表
$("#userlist").empty();
for (var i = 0; i < msg.data.length; i++) {
$("#userlist").append("<div>"+msg.data[i]+"</div>");
}
//更新在线人数
var lab = document.getElementById("lab");
lab.innerHTML = msg.data.length;
}else if(msg.code == 2){
$("#listcontent").append("<div>"+msg.message+"</div>");
}else if(msg.code == 3){
$("#listcontent").append("<div>"+msg.message+"</div>");
}
}
}
})
</script>
<div id="listcontent" class="content">
</div>
<div id="userlist">
</div>
<div class="ddd">当前用户: <label id="user-name"></label></div>
<div>
<input id="msg"><button style="margin-left: 3px" class="btn1" onclick="send()">发送</button>
<button class="btn2" onclick="sl()">私聊</button>
</div>
<script>
function send(){
ws.send(document.getElementById("msg").value);
$("#msg").val("");
}
//监听消息内容插入事件,滚动到底部
$("#listcontent").on('DOMNodeInserted',function(){
//滚动到底部
setTimeout(function(){
var boxElement=document.getElementById("listcontent");
boxElement.scrollTop=boxElement.scrollHeight-boxElement.clientHeight;
},100);
})
function sl(){
var me = prompt("请输入你私聊对象的账号: ");
ws.send(document.getElementById("msg").value+"="+me);
}
</script>
</body>
</html>
5.后台从Tomcat7.0.5开始支持WebSocoket,主要可以通过以下两种方式进行定义,本文章是使用注解方式实现的
- 第一种是编程式,即继承类javax.websocket.Endpoint并实现其方法。
- 第二种是注解式,添加@ServerEndpoint相关注解。
5.1建立连接的onOpen方法,使用hashMap保存连接用户的session的session中保存的用户名称
@OnOpen
public void onOpen(Session session, EndpointConfig endpointConfig) {
System.out.println("有客户端连接了");
String msg = session.getQueryString();
try {
msg = URLDecoder.decode(msg, "utf-8");
//对msg进行解析
String[] split = msg.split("=");
String loginUser = split[1];
//将session和用户名称保存到map集合中
sessionMap.put(session, loginUser);
Msg m = new Msg();
m.setCode(Msg.CHANGE);
m.setMessage(loginUser + "进入了聊天室");
List<String> list = new ArrayList<>();
for (Session s : sessionMap.keySet()) {
list.add(sessionMap.get(s));
}
m.setData(list);
boardcast(sessionMap.keySet(), JSON.toJSONString(m));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
5.2 onClose 当会话关闭时调用
//当前端socket关闭的时候
@OnClose
public void onClose(Session session) {
//将用户从聊天室移除
String name = sessionMap.get(session);
sessionMap.remove(session);
Msg m = new Msg();
m.setCode(Msg.CHANGE);
m.setMessage(name + "离开了聊天室");
List<String> list = new ArrayList<>();
for (Session s : sessionMap.keySet()) {
list.add(sessionMap.get(s));
}
m.setData(list);
boardcast(sessionMap.keySet(), JSON.toJSONString(m));
}
5.3服务器端通过onMessage接收前端用户ws.send()的消息
//浏览器中使用ws.send()的时候,服务器接收到的请求
@OnMessage
public void onMessage(String message, Session session) {
if (message.contains("=")){
//私聊
String[] split = message.split("=");
String name = sessionMap.get(session);
Msg ms = new Msg();
ms.setCode(Msg.SF);
ms.setMessage(name + ": " + split[0]);
System.out.println(split[0]);
Session sess = null;
for (Session s : sessionMap.keySet()) {
if (sessionMap.get(s).equals(split[1])) {
sess = s;
}
}
try {
session.getBasicRemote().sendText(JSON.toJSONString(ms));
sess.getBasicRemote().sendText(JSON.toJSONString(ms));
} catch (IOException e) {
throw new RuntimeException(e);
}
}else{
String name = sessionMap.get(session);
System.out.println(name);
Msg ms = new Msg();
ms.setCode(Msg.TEXT);
ms.setMessage(name + ": " + message);
boardcast(sessionMap.keySet(), JSON.toJSONString(ms));
}
}
5.4将其中一个客户端发送的消息广播给所有的客户端文章来源:https://www.toymoban.com/news/detail-595412.html
//广播
public void boardcast(Set<Session> sessionSet, String msg) {
for (Session s : sessionSet) {
try {
s.getBasicRemote().sendText(msg);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
5.5在springboot内置容器中运行时,必须提供ServerEndpointExporter 文章来源地址https://www.toymoban.com/news/detail-595412.html
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
到了这里,关于Springboot对Websocket的实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!