当前位置:网站首页>Implementation of web chat room
Implementation of web chat room
2022-07-04 15:07:00 【Full stack programmer webmaster】
Hello everyone , I meet you again , I'm your friend, Quan Jun .
Back end :
package com.jsx.chat;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import net.sf.json.JSONObject;
@ServerEndpoint("/websocket/{userId}")
public class ChatServer {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm"); // Date formatting
// Static variables , To record the current number of online connections . It should be designed to be thread safe .
private static int onlineCount = 0;
//concurrent Thread safety of package Set, Used to store the corresponding MyWebSocket object . If you want to realize the communication between the server and the single client , have access to Map To hold the , among Key It can identify the user
private static CopyOnWriteArraySet<ChatServer> webSocketSet = new CopyOnWriteArraySet<ChatServer>();
// A connection session with a client , It is needed to send data to the client
private Session session;
private String userId;
/**
* Connection establishment method called successfully
* @param session Optional parameters .session For a connection session with a client , It is needed to send data to the client
*/
@OnOpen
public void open(@PathParam("userId")String userIds,Session session) {
// Add initialization operation
System.out.println("--- initialization ----userId:"+userIds);
this.session = session;
// Get the id
this.userId = userIds;
webSocketSet.add(this); // Join in set in
addOnlineCount(); // The online number 1
System.out.println(" New connections are added ! The current online population is " + getOnlineCount());
}
/**
* Accept client messages , And send the message to all connected sessions
* @param message Messages from clients
* @param session Client's session
*/
@OnMessage
public void getMessage(String message, Session session1) {
// Parse the client message into JSON object
JSONObject jsonObject = JSONObject.fromObject(message);
// Add the sending date to the message
jsonObject.put("date", DATE_FORMAT.format(new Date()));
// ----------------------- Send messages to all connected sessions --------------------------------
System.out.println(" Message from the client "+this.userId+":" + message);
for(ChatServer item: webSocketSet){
try {
// The right side of the current user displays , The left side of non users displays
if(this.userId.equals(item.userId)){jsonObject.put("isSelf", true);}
else{jsonObject.put("isSelf", false);}
// send out JSON Formatted message
item.sendMessage(jsonObject.toString());
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
}
@OnClose
public void close() {
// Add actions when closing a session
webSocketSet.remove(this); // from set Delete in
subOnlineCount(); // The online number minus 1
System.out.println(" There is a connection closed ! The current online population is " + getOnlineCount());
}
@OnError
public void error(Throwable t) {
// Add actions to handle errors
System.out.println(" An error occurred ");
t.printStackTrace();
}
/**
* This method is different from the above methods . There is no comment , It is a method added according to your own needs .
* @param message json news
* @throws IOException
*/
public synchronized void sendMessage(String message) throws IOException{
this.session.getAsyncRemote().sendText(message);
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
ChatServer.onlineCount++;
}
public static synchronized void subOnlineCount() {
ChatServer.onlineCount--;
}
}front end :
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title> Instant group chat </title>
<meta name="renderer" content="webkit">
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link rel="stylesheet" href="css/chat.css">
<link rel="alternate icon" href="assets/i/favicon.ico">
<link rel="stylesheet" href="assets/css/amazeui.min.css">
<link rel="stylesheet" href="assets/css/app.css">
<link href="umeditor/themes/default/css/umeditor.css" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
}
.chat-content-container {
height: 29rem;
overflow-y: auto;
border: 1px solid silver;
border-bottom: 0px;
}
.container{
border: 1px solid #cdcaca;
padding:0px 0px;
}
.am-u-sm-6{
left:0px;
}
.am-u-sm-push-6{
width:100%;
}
</style>
</head>
<body>
<input id="username" type="hidden" value="${user.username}"><br>
<input id="name" type="hidden" value="${user.name}"><br>
<!-- Chat content box starts -->
<div class="am-container container" >
<div class="am-u-sm-12" style="background:#dcad50;">
<!-- <div class="am-u-sm-3 am-u-sm-push-6"> -->
<h3 style="text-align:center;margin-top:auto;margin-bottom:auto;padding:3px 0px;font-size:20px"> The chat room </h3>
<!-- </div> -->
</div>
<div class="chat-content-container">
<div class="am-u-sm-6 am-u-sm-push-6">
<ul id="message-list" class="am-comments-list am-comments-list-flip"></ul>
</div>
</div>
<!-- </div> -->
<!-- The chat content box ends -->
<div class="message-input am-margin-top">
<!-- Enter the content box to start -->
<div class="am-g am-g-fixed" style="padding:10px 0px;border-top:1px solid #b5a4a4">
<div class="am-u-sm-12">
<form class="am-form">
<div class="am-form-group">
<script type="text/plain" id="myEditor" style="width: 100%;height: 20rem;"></script>
</div>
</form>
</div>
</div>
<!-- Enter the nickname box to start -->
<!-- <div class="am-g am-g-fixed am-margin-top"> -->
<div class="am-u-sm-6" style="display: none;">
<div id="message-input-nickname" class="am-input-group am-input-group-primary">
<span class="am-input-group-label"><i class="am-icon-user"></i></span>
<input id="nickname" type="text" class="am-form-field" value="${user.name}"/>
</div>
</div>
<div class="am-u-sm-12">
<p style="text-align:right;margin:0px">
<button onclick="f()" class="am-btn am-btn-warning">
close
</button>
<button id="send" type="button" class="send am-btn am-btn-primary">
<i class="am-icon-send"></i> send out
</button>
</p>
</div>
<!-- </div> -->
<!-- </div> -->
</div>
</div>
<script src="assets/js/jquery.min.js"></script>
<script charset="utf-8" src="umeditor/umeditor.config.js"></script>
<script charset="utf-8" src="umeditor/umeditor.min.js"></script>
<script src="umeditor/lang/zh-cn/zh-cn.js"></script>
<script>
function f(){
window.location.href="friend.jsp";
}
$(function() {
var id = $('#username').val();
var name = $('#name').val();
// Random method Generate id Simulated users
function rand(num){
return parseInt(id);
}
// Initialize the message input box
var um = UM.getEditor('myEditor');
// Get the nickname box into focus
$('#nickname')[0].focus();
// newly build WebSocket object , final /WebSocket With the server side @ServerEndpoint("/websocket") Corresponding
//var socket = new WebSocket('ws://${pageContext.request.getServerName()}:${pageContext.request.getServerPort()}${pageContext.request.contextPath}/websocket');
//var socket = new WebSocket("ws://localhost:8080/Chat/websocket");
var target = "ws://"+window.location.host+"/Chat/websocket"+"/"+rand();
//alert(target);
var socket = new WebSocket(target);
// Process the data sent by the server
socket.onmessage = function(event) {
addMessage(event.data);
};
// Click on Send Button
$('#send').on('click', function() {
var nickname = $('#nickname').val();
//alert(um.getContent()); // Content
//alert(nickname); // nickname
if (!um.hasContents()) { // Judge whether the message input box is empty
// The message input box gets the focus
um.focus();
// Add dithering effect
$('.edui-container').addClass('am-animation-shake');
setTimeout("$('.edui-container').removeClass('am-animation-shake')", 1000);
} else if (nickname == '') { // Determine whether the nickname box is empty
// The nickname box gets the focus
$('#nickname')[0].focus();
// Add dithering effect
$('#message-input-nickname').addClass('am-animation-shake');
setTimeout("$('#message-input-nickname').removeClass('am-animation-shake')", 1000);
} else {
// Send a message
socket.send(JSON.stringify({
content : um.getContent(),
nickname : name
}));
// Clear the message input box
um.setContent('');
// The message input box gets the focus
um.focus();
}
});
// Add a message to the chat
function addMessage(message) {
message = JSON.parse(message);
var messageItem = '<li class="am-comment '
+ (message.isSelf ? 'am-comment-flip' : 'am-comment')
+ '">'
+ '<a href="javascript:void(0)" ><img src="assets/images/'
+ (message.isSelf ? 'self.jpg' : 'others.jpg')
+ '" alt="" class="am-comment-avatar" width="48" height="48"/></a>'
+ '<div class="am-comment-main"><header class="am-comment-hd"><div class="am-comment-meta">'
+ '<a href="javascript:void(0)" class="am-comment-author">'
+ message.nickname + '</a> <time>' + message.date
+ '</time></div></header>'
+ '<div class="am-comment-bd">' + message.content
+ '</div></div></li>';
$(messageItem).appendTo('#message-list');
// Scroll the scroll bar to the bottom
$(".chat-content-container").scrollTop($(".chat-content-container")[0].scrollHeight);
}
});
</script>
</body>
</html>Because my account design, database and other operations , Therefore, if you want to test directly, you can modify the above nickname The value in is randomly generated !
Publisher : Full stack programmer stack length , Reprint please indicate the source :https://javaforall.cn/149294.html Link to the original text :https://javaforall.cn
边栏推荐
- Redis 发布和订阅
- Ffprobe common commands
- Five minutes per day machine learning: use gradient descent to complete the fitting of multi feature linear regression model
- PLC模拟量输入 模拟量转换FC S_ITR (CODESYS平台)
- 从0到1建设智能灰度数据体系:以vivo游戏中心为例
- 5G电视难成竞争优势,视频资源成中国广电最后武器
- Luo Gu - some interesting questions
- Openresty current limiting
- 左右对齐!
- 一篇文章搞懂Go语言中的Context
猜你喜欢

各大主流编程语言性能PK,结果出乎意料
![[differential privacy and data adaptability] differential privacy code implementation series (XIV)](/img/de/c053f376fe90c2697ffc640fab57e8.jpg)
[differential privacy and data adaptability] differential privacy code implementation series (XIV)

TechSmith Camtasia studio 2022.0.2 screen recording software
![Leetcode 1200 minimum absolute difference [sort] the way of leetcode in heroding](/img/4a/6763e3fbdeaf9de673fbe8eaf96858.png)
Leetcode 1200 minimum absolute difference [sort] the way of leetcode in heroding

Programmers exposed that they took private jobs: they took more than 30 orders in 10 months, with a net income of 400000

MP3是如何诞生的?

Force button brush question 01 (reverse linked list + sliding window +lru cache mechanism)

Introduction to modern control theory + understanding

Guitar Pro 8win10最新版吉他学习 / 打谱 / 创作

Flutter reports an error no mediaquery widget ancestor found
随机推荐
Luo Gu - some interesting questions
从0到1建设智能灰度数据体系:以vivo游戏中心为例
毕业季-个人总结
Redis publish and subscribe
Implementation of macro instruction of first-order RC low-pass filter in signal processing (easy touch screen)
Kubernets pod exists finalizers are always in terminating state
Exploration and practice of eventbridge in the field of SaaS enterprise integration
Why do domestic mobile phone users choose iPhone when changing a mobile phone?
一篇文章学会GO语言中的变量
信号处理之一阶RC低通滤波器宏指令实现(繁易触摸屏)
Analysis of nearly 100 million dollars stolen and horizon cross chain bridge attacked
web聊天室实现
LVGL 8.2 Menu
LVGL 8.2 Draw label with gradient color
Halcon knowledge: NCC_ Model template matching
韩国AI团队抄袭震动学界!1个导师带51个学生,还是抄袭惯犯
Leetcode 1200 minimum absolute difference [sort] the way of leetcode in heroding
LeetCode 1200 最小絕對差[排序] HERODING的LeetCode之路
金额计算用 BigDecimal 就万无一失了?看看这五个坑吧~~
Is BigDecimal safe to calculate the amount? Look at these five pits~~