分享基于 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端聊天室— ...
随机推荐
- 我的微服务观,surging 2.0将会带来多大的改变
Surging 自2017年6月16日开源以来,已收到不少公司的关注或者使用,其中既有以海克斯康超大型等外企的关注,也不乏深圳泓达康.重庆金翅膀等传统行业的正式使用,自2019年年初,surging2 ...
- Android 7.0 存储系统—Vold与MountService分析(二)(转 Android 9.0 分析)
Android的存储系统(二) 回顾:前贴主要分析了Android存储系统的架构和原理图,简要的介绍了整个从Kernel-->Vold-->上层MountService之间的数据传输流程, ...
- 【Python3爬虫】你会怎么评价复仇者联盟4?
一.写在前面 最近复仇者联盟4正在热映中,很多人都去电影院观看了电影,那么对于这部电影,看过的人都是怎么评价的呢?这时候爬虫就可以派上用场了! 二.主要思路 首先打开豆瓣电影,然后进入复仇者联盟4的详 ...
- 机器学习周志华 pdf统计学习人工智能资料下载
周志华-机器学习 pdf,下载地址: https://u12230716.pipipan.com/fs/12230716-239561959 统计学习方法-李航, 下载地址: https://u12 ...
- javascript正则表达式学习(二)--位置匹配
文章首发于sau交流学习社区 一.前言 正则表达式是匹配模式,要么是匹配字符,要么匹配位置. 其实在开发中很少用到匹配位置,本篇文章主要包含: 二.什么是位置 位置:相邻字符之间的位置. 三.如何匹配 ...
- Java开发必须掌握的线上问题排查命令
作为一个合格的开发人员,不仅要能写得一手还代码,还有一项很重要的技能就是排查问题.这里提到的排查问题不仅仅是在coding的过程中debug等,还包括的就是线上问题的排查.由于在生产环境中,一般没办法 ...
- 使用NSSM把.Net Core部署至 Windows 服务
为什么部署至Windows Services 在很多情况下,很少会把.Net Core项目部署至Windows服务中,特别是Asp.net Core就更少了.一般情况下,Asp.net Core会部署 ...
- Electron学习笔记(一)
Electron是使用Javascript.HTML5技术构建跨平台桌面应用的技术,是目前非常活跃的一项技术,其中比较有名气的应用有微软的VS Code. 创建一个Electron应用的方式有很多,G ...
- .net core redis 驱动推荐,为什么不使用 StackExchange.Redis
前言 本人从事 .netcore 转型已两年有余,对 .net core 颇有好感,这一切得益于优秀的语法.框架设计. 2006年开始使用 .net 2.0,从 asp.net 到 winform 到 ...
- Redis数据结构和常用API
Redis是一个速度非常快的非关系型数据库,可以存储键与5中不同数据结构类型之间的映射.这5种数据结构分别是STRING(字符串).LIST(列表).SET(集合).HASH(散列).ZSET(有序集 ...