WebScoket 实例 简单的网页聊天室
程序员文章站
2022-05-19 17:36:16
...
WebScoket 是H5的新特性 具体的可以百度,
首先html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
* {
margin: 0px;
padding: 0px;
}
#container {
border: 1px solid;
position: relative;
margin: auto;
margin-top: 50px;
width: 500px;
height: 500px;
}
#text-container {
border-top: 1px solid;
position: absolute;
width: 100%;
height: 100px;
bottom: 0px;
}
#link-container {
position: absolute;
width: 100%;
height: 40px;
border-bottom: 1px solid;
}
#link-container input {
margin-left: 10px;
border: none;
outline: medium;
border: 0.5px solid;
width: 120px;
margin-top: 5px;
height: 30px;
}
#link-container #link-server {
display: inline-block;
border: 0.5px solid;
text-align: center;
line-height: 28px;
width: 50px;
height: 28px;
}
#text-container textarea {
position: absolute;
font-size: 24px;
margin-left: 2px;
width: 80%;
height: 90%;
border: none;
outline: medium;
}
#send {
position: absolute;
left: 80%;
width: 20%;
height: 100%;
text-align: center;
line-height: 100px;
border-left: 1px solid;
font-size: 24px;
}
#chat-body {
position: absolute;
top: 42px;
width: 100%;
height: 355px;
overflow: auto;
overflow-y: auto;
}
.mymsg {
position: absolute;
top: 50px;
width: 180px;
height: auto;
word-wrap: break-word;
word-break: break-all;
overflow: hidden;
right: 5px;
}
.hermsg {
position: absolute;
top: 100px;
width: 180px;
text-align: left;
height: auto;
word-wrap: break-word;
word-break: break-all;
overflow: hidden;
left: 5px;
}
</style>
<title>聊天室</title>
<body>
<div id="container">
<div id="link-container">
输入姓名: <input type="text" name="" id="name" value="" /> <span
id="link-server"> 链接 </span>
</div>
<div id="chat-body">
<span></span>
</div>
<div id="text-container">
<textarea name="" rows="" cols=""></textarea>
<div id="send">发送</div>
</div>
</div>
</head>
</body>
<script src="js/jquery-1.9.0.min.js" type="text/javascript"
charset="utf-8"></script>
<script type="text/javascript">
var socket;
$("#link-server").click(function() {
var name = $("#name").val()
if (name == "") {
alert("请输入姓名")
} else {
var url = "ws://localhost:8080/chartRoom/room/" + name;
socket = new WebSocket(url);
socket.onopen = function() {
alert("链接成功")
}
socket.onclose = function(event) {
alert("服务器断开链接")
};
//接收数据事件
socket.onmessage = function(event) {
var span = "<span class='hermsg'>" + event.data + "</span>"
var li = $("#chat-body span:last-child").css([ 'top', 'height' ]);
var top = li.top;
var height = li.height;
$("#chat-body").append(span)
var top1 = parseInt(top.substring(0, top.length - 2));
var heigth1 = parseInt(height.substring(0, height.length - 2));
var tops = top1 + heigth1 + 15;
$("#chat-body span:last-child").css({
"top" : tops + "px"
})
}
}
})
$("#send").click(function() {
var msg = $("#text-container textarea").val();
if (msg == "") {
alert("请输入内容")
} else {
socket.send(msg);
var span = "<span class='mymsg'>" + "我说:" + msg + "</span>"
var li = $("#chat-body span:last-child").css([ 'top', 'height' ]);
var top = li.top;
var height = li.height;
$("#chat-body").append(span)
var top1 = parseInt(top.substring(0, top.length - 2));
var heigth1 = parseInt(height.substring(0, height.length - 2));
var tops = top1 + heigth1 + 15;
$("#chat-body span:last-child").css({
"top" : tops + "px"
})
reset()
}
})
//清空输入框
function reset() {
$("#text-container textarea").val("");
}
//在浏览器刷新或者关闭的时候断开链接
window.onbeforeunload = function() {
socket.close();
}
</script>
</html>
再是服务端的代码。。
前端需要注意的是 new WebScoket中的 url 其写法为"ws://localhost:8080/chartRoom/room/" + name;
名称以ws开头 类似于http 再是你的ip地址和端口号 charRoom为项目的名称 room为当前服务端@ServerEndpoint("/room/{param}")中注解的 地址 name就是注解中的参数 param
package com.qhit.web.scoket;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.CloseReason;
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;
//这里的parm是浏览器传来的参数
@ServerEndpoint("/room/{param}")
public class ChartRoom {
private Session session;
private String name;
//这里采用线程安全的set单例集合来存放聊天室的用户对象
private static CopyOnWriteArraySet<ChartRoom> set = new CopyOnWriteArraySet<>();
// 连接打开时执行
@OnOpen
public void onOpen(@PathParam(value = "param") String param, Session session) throws IOException {
//因为我用的tomcat版本是7.0的所以要进行转码
String name = new String(param.getBytes("iso8859-1"), "utf-8");
System.out.println(name);
this.name = name;
this.session = session;
set.add(this);
System.out.println("欢迎" + this.name + "进入聊天室");
//如果这个集合 不为空 则遍历集合 给每个用户 发送消息
if (set != null) {
for (ChartRoom chartRoom : set) {
chartRoom.sendMessage("欢迎" + this.name + "进入聊天室");
}
} else {
sendMessage("欢迎" + this.name + "进入聊天室");
}
}
// 收到消息时执行
@OnMessage
public void onMessage(String message, Session session) {
//客户端收到消息的时候 遍历集合 然后实现消息的广播
for (ChartRoom socket : set) {
try {
if (socket != this) {
//这里是自定义的广播方法
socket.sendMessage(this.name + "说:" + message);
}
} catch (IOException e) {
}
}
}
// 连接关闭时执行
@OnClose
public void onClose(Session session, CloseReason closeReason) {
//当用户退出的时候 在set集合中删除当前对象
set.remove(this);
System.out.println(this.name+"退出了聊天室");
}
// 连接错误时执行
@OnError
public void onError(Throwable t) {
t.printStackTrace();
}
// 自定义的方法,用于发送消息
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
// this.session.getAsyncRemote().sendText(message);
}
}
这样 一个简单的聊天室就写好了
下面看 效果图把