博客地址: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>

到这里大功告成

聊天方法

  1. 打开两个窗口输入项目地址进行聊天
  2. 可以把链接发给朋友打开,进行聊天

来一波截图

移动端

在线演示

PC 端:https://www.ainyi.com/krry_NetChat

移动端:https://www.ainyi.com/krry_NetChatPho

打完收工~

博客地址:https://ainyi.com/67

分享基于 websocket 网页端聊天室的更多相关文章

  1. java 开发 websocket 网页端聊天室

    博客地址:https://ainyi.com/67 WebSocket协议是基于TCP的一种新的网络协议.它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端. ...

  2. workerman-chat(PHP开发的基于Websocket协议的聊天室框架)(thinkphp也是支持socket聊天的)

    workerman-chat(PHP开发的基于Websocket协议的聊天室框架)(thinkphp也是支持socket聊天的) 一.总结 1.下面链接里面还有一个来聊的php聊天室源码可以学习 2. ...

  3. .NET Core 基于Websocket的在线聊天室

    什么是Websocket 我们在传统的客户端程序要实现实时双工通讯第一想到的技术就是socket通讯,但是在web体系是用不了socket通讯技术的,因为http被设计成无状态,每次跟服务器通讯完成后 ...

  4. Netty 系列八(基于 WebSocket 的简单聊天室).

    一.前言 之前写过一篇 Spring 集成 WebSocket 协议的文章 —— Spring消息之WebSocket ,所以对于 WebSocket 协议的介绍就不多说了,可以参考这篇文章.这里只做 ...

  5. Flask基于websocket的简单聊天室

    1.安装gevent-websocket pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ gevent-websocket 2.cha ...

  6. 基于WebSocket的简易聊天室

    用的是Flash + WebSocket 哦~ Flask 之 WebSocket 一.项目结构: 二.导入模块 pip3 install gevent-websocket 三.先来看一个一对一聊天的 ...

  7. 如何利用WebSocket实现网页版聊天室

    花了将近一周的时间终于完成了利用WebSocket完成网页版聊天室这个小demo,期间还走过了一段"看似弯曲"的道路,但是我想其实也不算是弯路吧,因为你走过的路必将留下你的足迹.这 ...

  8. 基于Node.js + WebSocket 的简易聊天室

    代码地址如下:http://www.demodashi.com/demo/13282.html Node.js聊天室运行说明 Node.js的本质就是运行在服务端的JavaScript.Node.js ...

  9. vue仿微信网页版|vue+web端聊天室|仿微信客户端vue版

    一.项目介绍 基于Vue2.5.6+Vuex+vue-cli+vue-router+vue-gemini-scrollbar+swiper+elementUI等技术混合架构开发的仿微信web端聊天室— ...

随机推荐

  1. BZOJ3252: 攻略 可并堆

    网上有很多人说用dfs序+线段树做...其实stl的堆可以...可并堆可以...很多奇奇怪怪的东西都能做... 可并堆比较好想...也比较好写... 分析: 首先,这是一个网络流做不了的题...数据太 ...

  2. BZOJ 1412 狼和羊的故事

    首先,题目目的就是为了分割狼群和羊群,即建立超级源和超级汇求最小割从而转化成用网络流来处理. 如果没有空地,那么就是简单的二分图最大匹配,但是题中有空地的出现,所以需要在点与点之间建立双向边(不算后向 ...

  3. CSS3实例分享之多重背景的实现(Multiple backgrounds)

    CSS3的诞生为我们解决了这一问题,在CSS3里,通过background-image或者background可以为一个容器设置多张背景图像,也就是说可以把不同背景图象只放到一个块元素里. 首先我们来 ...

  4. Mtcnn进行人脸剪裁和对齐B

    Mtcnn进行人脸剪裁和对齐 from scipy import misc import tensorflow as tf import detect_face import cv2 # import ...

  5. MIUI目前为止最简单安装谷歌服务框架教程

    安装谷歌服务框架方法有很多,比如用第三方 rec卡刷gapps包.用第三方工具安装......然而这些对于新手来说还是比较难的! 我今天说的方法可以说是最简单的:1.不需要修改文件:2.不需要借助第三 ...

  6. ElasticSearch入门 附.Net Core例子

    1.什么是ElasticSearch? Elasticsearch是基于Lucene的搜索引擎.它提供了一个分布式,支持多租户的全文搜索引擎,它具有HTTP Web界面和无模式JSON文档. Elas ...

  7. .NET(C#、VB)APP开发——Smobiler平台控件介绍:SliderView控件

    SliderView控件 一.          样式一 我们要实现上图中的效果,需要如下的操作: 从工具栏上的“Smobiler Components”拖动一个SliderView控件到窗体界面上 ...

  8. (一)初识Redis

    1.redis简介 Redis是一个速度非常快的key-value非关系型存储数据库,可以存储5种形态的键值对,可以将存储在内存中的键值对持久化到硬盘,可以使用复制特性扩展读性能,还可以使用客户端分片 ...

  9. windows系统中,在当前目录下打开cmd命令行的两种方法

    1.在当前路径地址栏中直接输入‘cmd’,然后回车. 2.在当前路径下,按住‘shift’键同时点击鼠标右键,点击“在此处打开Powershell”. 其实你会发现,两个命令行有很大的区别. cmd: ...

  10. 原生的 django 分页

    原始的 django 分页 # 基本 写法 class Paginator(object): def __init__(self, object_list, per_page, orphans=0, ...