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

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

需要导入一个jar包:javax.websocket-api-1.0-rc4.jar

注意点:

需要实现这几个方法:

 //注册事件
ws.onopen = function(){
openWs();
};
ws.onmessage = function(event){
msgWs(event);
};
ws.onclose = function(){
closeWs();
};
ws.onerror = function(){
errorWs();
};

后台代码:

 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--;
}
}

前端代码:

 <%@ 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="localhost/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 = "ws://"+$(".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>

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

java 开发 websocket 网页端聊天室的更多相关文章

  1. 分享基于 websocket 网页端聊天室

    博客地址:https://ainyi.com/67 有一个月没有写博客了,也是因为年前需求多.回家过春节的原因,现在返回北京的第二天,想想,应该也要分享技术专题的博客了!! 主题 基于 websock ...

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

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

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

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

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

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

  5. 与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室

    原文:与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

  6. 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室

    原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

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

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

  8. XMPPFrameWork IOS 开发(六)聊天室

    原始地址:XMPPFrameWork IOS 开发(六)聊天室 聊天室 //初始化聊天室 XMPPJID *roomJID = [XMPPJID jidWithString:ROOM_JID]; xm ...

  9. JAVA实现webSocket网页聊天室

    一.什么是webSocket WebSocket 是一种网络通信协议,是持久化协议.RFC6455 定义了它的通信标准. WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全 ...

随机推荐

  1. 安装xgboost

    http://blog.csdn.net/xizero00/article/details/73008330,python2.7 和python3.5 都可以安装成功.

  2. bash基础特性3(shell编程)

    Linux上文本处理三剑客: grep:文本过滤工具 sed:stream editor,文本编辑工具 awk:文本报告生成器 grep -v:显示不能够被pattern匹配到的行 -i:忽略字符大小 ...

  3. PSR-PHP开发规范(本文版权归作者:luluyrt@163.com)

    遵循PSR-4的自动加载 一.简介 首先这里要了解PSR,Proposing a Standards Recommendation(提出标准建议)的缩写,就是一种PHP开发规范,让我们研发出来的代码更 ...

  4. Must Know Tips/Tricks in Deep Neural Networks

    Must Know Tips/Tricks in Deep Neural Networks (by Xiu-Shen Wei)   Deep Neural Networks, especially C ...

  5. Javascript高级编程学习笔记(58)—— 事件(2)事件处理程序

    事件处理程序 事件处理程序即响应某个事件的函数 事件处理程序以 “on” 开头 如“onclick”,“onload” HTML事件处理程序 某个元素支持的每种事件都可以使用一个与响应的事件处理程序同 ...

  6. PHP新特性Trait

    Trait是PHP 5.4引入的新概念,看上去既像类又像接口,其实都不是,Trait可以看做类的部分实现,可以混入一个或多个现有的PHP类中,其作用有两个:表明类可以做什么:提供模块化实现.Trait ...

  7. Hexo博客主题优化

    Hexo博客主题优化 添加背景图 在 themes/*/source/css/_custom/custom.styl 中添加如下代码: body{ background:url(/images/bg. ...

  8. postgresql 日志配置

    Postgresql日志收集   PG安装完成后默认不会记录日志,必须修改对应的(${PGDATA}/postgresql.conf)配置才可以,这里只介绍常用的日志配置. 1.logging_col ...

  9. PLSQL使用scott登录

    Oracle有3种用户: system.sys.scott,其中system和sys的区别在与能否创建数据库,sys用户登录才可以创建数据库,而scott是给初学者学习的用户,学习者可以用Scott登 ...

  10. java中最常见的几种运行时异常,你get了吗?

    NullPointerException (空指针异常) ClassCastException (类型强制转换异常) NumberFormatException (数字格式异常) NegativeAr ...