分享基于 websocket 网页端聊天室
博客地址:https://ainyi.com/67
有一个月没有写博客了,也是因为年前需求多、回家过春节的原因,现在返回北京的第二天,想想,应该也要分享技术专题的博客了!!
主题
基于 websocket 网页端聊天室
WebSocket 协议是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工 (full-duplex) 通信——允许服务器主动发送信息给客户端。
使用 java 开发后台
需要导入一个jar包:javax.websocket-api-1.0-rc4.jar
后台代码
package com.krry.socket;
import java.io.IOException;
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.ServerEndpoint;
//该注解用来指定一个URI,客户端可以通过这个URI来连接到WebSocket。类似Servlet的注解mapping。无需在web.xml中配置。
@ServerEndpoint("/websocket")
public class MyWebSocket {
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
/**
* 连接建立成功调用的方法
* @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
@OnOpen
public void onOpen(Session session){
this.session = session;
webSocketSet.add(this); //加入set中
addOnlineCount(); //在线数加1
System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(){
webSocketSet.remove(this); //从set中删除
subOnlineCount(); //在线数减1
System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
* @param message 客户端发送过来的消息
* @param session 可选的参数
*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("来自客户端的消息:" + message);
//群发消息
for(MyWebSocket item: webSocketSet){
try {
item.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
}
/**
* 发生错误时调用
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error){
System.out.println("发生错误");
error.printStackTrace();
}
/**
* 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException{
this.session.getBasicRemote().sendText(message);
//this.session.getAsyncRemote().sendText(message);
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
MyWebSocket.onlineCount++;
}
public static synchronized void subOnlineCount() {
MyWebSocket.onlineCount--;
}
}
前端代码
注意
前端需要实现这几个方法:
// 注册事件
// 监听打开连接
ws.onopen = function(){
openWs();
};
// 监听消息
ws.onmessage = function(event){
msgWs(event);
};
// 监听关闭连接
ws.onclose = function(){
closeWs();
};
// 监听发送错误
ws.onerror = function(){
errorWs();
};
具体代码
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta name="keywords" content="">
<meta name="description" content="">
<title>
基于Java服务器端的消息主动推送技术揭秘 --krry
</title>
<link rel="stylesheet" href="css/animate.css" />
<link rel="stylesheet" type="text/css" href="css/sg.css" />
<style>
*{margin:0;padding:0;} body{background:url("images/5.jpg");background-size:cover;}
h1{margin-top:50px;text-align:center;color:#fff;text-shadow:1px 1px 1px
#000;font-family:-webkit-body;font-size:24px;} .box{width:700px;margin:20px
auto;} .box span{color:#f60;font-size:16px;font-family:"微软雅黑";} .box .shu{text-indent:1em;height:24px;font-family:"微软雅黑";border:0;outline:none;font-size:14px;}
.box .add{width:300px;margin-right:24px;} .box .user{width:200px;} .box
.btn{width:80px;height:34px;color:#fff;background:#6c0;border:0;outline:none;cursor:pointer;margin-top:20px;font-size:16px;font-family:"微软雅黑";}
.box .area{line-height: 29px;height:280px;width:680px;padding:10px;overflow:auto;font-size:16px;font-family:"微软雅黑";margin:20px
0;outline:none;box-shadow:1px 2px 18px #000} .box .setex{text-indent:1em;height:28px;border:1px
solid #6c0;width:618px;outline:none;float:left;font-family:"微软雅黑";} .box
.send{font-size:14px;width:80px;height:30px;color:#fff;background:#6c0;border:0;outline:none;cursor:pointer;font-family:"微软雅黑";}
</style>
</head>
<body>
<h1>
基于Java服务器端的消息主动推送技术揭秘 --krry
</h1>
<div class="box">
<span>
服务器地址:
</span>
<input type="text" class="shu add" value="www.ainyi.com/krry_NetChat/websocket"
readonly/>
<span>
用户名:
</span>
<input type="text" class="shu user" value="匿名" />
<input type="button" value="连接" class="btn" />
<div class="area" id="boxx">
</div>
<div class="c_cen">
<input type="text" class="setex" />
<input type="button" value="发送" class="send">
</div>
</div>
<script src="js/jquery-1.11.1.min.js">
</script>
<script src="js/sg.js">
</script>
<script src="js/sgutil.js">
</script>
<script>
var close = true;
var ws;
$(function() {
$(".c_cen").hide();
//首先判断浏览器是否支持webSocket,支持h5的浏览器才会支持
if (window.WebSocket) {
printMsg("您的浏览器支持WebSocket,您可以尝试连接到聊天服务器!", "OK");
} else {
printMsg("您的浏览器不支持WebSocket,请选择其他浏览器!", "ERROR");
//设置按钮不可点击
$(".btn").attr("disabled", "true");
}
});
//打印信息
function printMsg(msg, msgType) {
if (msgType == "OK") {
msg = "<span style='color:green'>" + msg + "</span>";
}
if (msgType == "ERROR") {
msg = "<span style='color:red'>" + msg + "</span>";
}
$(".area").append(msg + "<br/>");
var boxx = document.getElementById("boxx");
boxx.scrollTop = boxx.scrollHeight; //使滚动条一直在底部
}
//打开Socket
function openWs() {
printMsg("链接已建立", "OK");
ws.send("【" + $(".user").val() + "】已进入聊天室");
$(".c_cen").show();
}
//接收消息的时候
function msgWs(e) {
printMsg(e.data);
}
//关闭连接
function closeWs() {
$(".btn").val("连接");
$(".c_cen").hide();
}
//产生错误
function errorWs() {
printMsg("您与服务器连接错误...", "ERROR");
}
//点击发送按钮
$(".send").click(function() {
var text = $(".setex").val();
if (text == null || text == "") return;
$(".setex").val("");
ws.send("【" + $(".user").val() + "】:" + text);
});
//点击连接
$(".btn").click(function() {
if ($(".add").val() && $(".user").val()) {
if (close) {
printMsg("正在准备连接服务器,请稍等...");
var url = "wss://" + $(".add").val();
if ("WebSocket" in window) {
ws = new WebSocket(url);
} else if ("MozWebSocket" in window) {
ws = new MozWebSocket(url);
}
//已连接
$(".btn").val("断开");
close = false;
//注册事件
ws.onopen = function() {
openWs();
};
ws.onmessage = function(event) {
msgWs(event);
};
ws.onclose = function() {
closeWs();
};
ws.onerror = function() {
errorWs();
};
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
ws.send("【" + $(".user").val() + "】离开了聊天室");
close = true;
ws.close();
};
} else {
ws.send("【" + $(".user").val() + "】离开了聊天室");
close = true;
ws.close();
}
} else {
$.tmDialog.alert({
open: "left",
content: "服务器地址和用户名不能为空哦...",
title: "提示哦~~~"
});
}
});
//回车键
$(".setex").keypress(function(event) {
if (event.keyCode == 13) {
$(".send").trigger("click");
}
});
</script>
</body>
</html>
到这里大功告成
聊天方法
- 打开两个窗口输入项目地址进行聊天
- 可以把链接发给朋友打开,进行聊天
来一波截图


移动端


在线演示
PC 端:https://www.ainyi.com/krry_NetChat
移动端:https://www.ainyi.com/krry_NetChatPho
打完收工~
博客地址:https://ainyi.com/67
分享基于 websocket 网页端聊天室的更多相关文章
- java 开发 websocket 网页端聊天室
博客地址:https://ainyi.com/67 WebSocket协议是基于TCP的一种新的网络协议.它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端. ...
- workerman-chat(PHP开发的基于Websocket协议的聊天室框架)(thinkphp也是支持socket聊天的)
workerman-chat(PHP开发的基于Websocket协议的聊天室框架)(thinkphp也是支持socket聊天的) 一.总结 1.下面链接里面还有一个来聊的php聊天室源码可以学习 2. ...
- .NET Core 基于Websocket的在线聊天室
什么是Websocket 我们在传统的客户端程序要实现实时双工通讯第一想到的技术就是socket通讯,但是在web体系是用不了socket通讯技术的,因为http被设计成无状态,每次跟服务器通讯完成后 ...
- Netty 系列八(基于 WebSocket 的简单聊天室).
一.前言 之前写过一篇 Spring 集成 WebSocket 协议的文章 —— Spring消息之WebSocket ,所以对于 WebSocket 协议的介绍就不多说了,可以参考这篇文章.这里只做 ...
- Flask基于websocket的简单聊天室
1.安装gevent-websocket pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ gevent-websocket 2.cha ...
- 基于WebSocket的简易聊天室
用的是Flash + WebSocket 哦~ Flask 之 WebSocket 一.项目结构: 二.导入模块 pip3 install gevent-websocket 三.先来看一个一对一聊天的 ...
- 如何利用WebSocket实现网页版聊天室
花了将近一周的时间终于完成了利用WebSocket完成网页版聊天室这个小demo,期间还走过了一段"看似弯曲"的道路,但是我想其实也不算是弯路吧,因为你走过的路必将留下你的足迹.这 ...
- 基于Node.js + WebSocket 的简易聊天室
代码地址如下:http://www.demodashi.com/demo/13282.html Node.js聊天室运行说明 Node.js的本质就是运行在服务端的JavaScript.Node.js ...
- vue仿微信网页版|vue+web端聊天室|仿微信客户端vue版
一.项目介绍 基于Vue2.5.6+Vuex+vue-cli+vue-router+vue-gemini-scrollbar+swiper+elementUI等技术混合架构开发的仿微信web端聊天室— ...
随机推荐
- BZOJ_1579_[Usaco2009 Feb]Revamping Trails 道路升级_分层图最短路
BZOJ_1579_[Usaco2009 Feb]Revamping Trails 道路升级_分层图最短路 Description 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M ...
- Linux 下配置Nginx,MySql,php-fpm开机启动
一. Nginx 开机启动 1.在/etc/init.d/目录下创建脚本 vim /etc/init.d/nginx 2.编写脚本内容 (将以下复制进去相应改动安装路径) #!/bin/bash # ...
- ServletContextListener
在 Servlet API 中有一个 ServletContextListener 接口,它能够监听 ServletContext 对象的生命周期,实际上就是监听 Web 应用的生命周期. 当Serv ...
- HrbustOJ 1564 螺旋矩阵
Description 对于给定的一个数n,要你打印n*n的螺旋矩阵. 比如n=3时,输出: 1 2 3 8 9 4 7 6 5 Input 多组测试数据,每个测试数据包含一个整数n(1<=n& ...
- 循环table 示例
1.循环table里的某一列 //当前第三列 //注:索引从1开始 $("#tabcardno tr td:nth-child(3)").each(function () { va ...
- SOLID原则(OOD&OOP)
SOLID原则是面向对象编程和面向对象设计的头五大原则.学习及应用这五大原则可以构建一个易于维护和扩展的应用程序,我们一起看看到底是那五大原则. S--单一责任原则(SRP) --Single Res ...
- asp.net core 3.0 gRPC框架小试
什么是gRPC gRPC是google开源的一个高性能.跨语言的RPC框架,基于HTTP2协议,采用ProtoBuf 定义的IDL. gRPC 的主要优点是: 现代高性能轻量级 RPC 框架. 协定优 ...
- 聊一聊快速排序(Js)
快速排序 基本思路 双指针+递归分治(本质是一个创建二叉树搜索树的过程) 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据 ...
- 原生js获取pc和移动端屏幕宽、高的方法
pc端: var w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; ...
- EFCore中 join on的不同
当 多条件 left join on 时 LEFT OUTER JOIN on new { u.UserId, ue.ExamId } equals new { sac.UserId, sac.Exa ...