html面页与JAVA通过webSocket 通讯
(原)
往常前后端通讯基本都是以ajax请求或是表单做数据交互的,这是一种无状态的http协议,如果要做tcp协议的数据交互,能想到的技术也就socket了,可如果后端是JAVA,前端如何做socket呢,在html5出来之前,只能用ajax轮询,html5中有定义了一个新的数据传输协议,webSocket,这是一种长连接协议,类似于socket,html5出来好些年了,基本主流浏览器的最新版本都支持,在js中用window.WebScoket就可以得到它,它的API很简单,这里暂不介绍,这里介绍一下对其封装的一个第三方js库,socket.io,下面来看看如何实现吧。
1、你必需知道socket.io实际上就是一个js文件,它可以在这下载。(https://github.com/socketio/socket.io-client)
上面也写的很清楚了,最简单的使用方法,也就几行代码。
2、你需要知道JAVA端怎么写最方便,实现已经有第三方针对于socket.io完成了JAVA端的实现,只用引入JAR包,调用相应的API就行了,它跟socket.io有个相对应的名字,叫netty-socketio。它可以在这里下载。(https://github.com/mrniko/netty-socketio)
它的文档里也写了一大堆,实际上你如果要最快的上手,只需要这一句话就够了。
netty-socketio的1.6.6版本支持socket.io1.0以下的版本,最新版的netty-socketio支持1.0以上的socket.io版本。
(别混了概念,netty-socketio指的是JAVA端的一个JAR,socket.io指的是一个JS文件)
3.这里就以最新版本以例。
先写前端。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>demo</title>
<script src="js/jquery/jquery-1.8.3.min.js" type="text/javascript"></script>
<script type="text/javascript" src="js/socket.io/socket.io.js"></script> </head>
<body> </body>
<script type="text/javascript">
//创建TCP连接
var socket = io.connect('http://192.168.0.104:8998');
//连接成功后会监听到
socket.on('connect',function() {
output('<span>连接成功</span>');
}); socket.on('connecting',function() {
output('<span>正在连接...</span>');
}); socket.on('disconnect',function() {
output('<span>断开连接! </span>');
}); socket.on('reconnecting',function() {
output('<span>正在重连...</span>');
}); socket.on('reconnect',function() {
output('<span>成功重连!</span>');
}); socket.on('connect_failed',function() {
output('<span>连接失败!</span>');
}); //想要断开连接调用此方法
function sendDisconnect() {
socket.disconnect();
}
//下面的testMessage是自定义的。
socket.emit('testMessage', 'Hello',function(){
output('<span>' + data + '</span>');
});
//socket.emit('testMessage', '你好',function(){
// output('<span>' + data + '</span>');
//});
//这里是监听服务端返回的testMessage事件
//socket.on('testMessage',function(data){
// output('<span>' + data + '</span>');
//}); function output(message) {
var currentTime = "<span class='time' >" + new Date().toLocaleString() + "</span>";
var element = $("<div>" + currentTime + " " + message + "</div>");
$('body').prepend(element);
} </script>
</html>
我们叫这个页面为demo.html
然后再写JAVA后端
只需要二个类,一个是开启socket服务的类,一个是监听的类,这里只监听客户端的连接,断开和发送testMessage消息。
package com.ewin.ccr; import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.ConnectListener;
import com.corundumstudio.socketio.listener.DataListener;
import com.corundumstudio.socketio.listener.DisconnectListener; public class SocketListener implements ConnectListener ,DisconnectListener,DataListener<String>{
private SocketIOServer server; public SocketListener(SocketIOServer server){
this.server = server;
} @Override
public void onConnect(SocketIOClient client) {
Integer clientSize = server.getAllClients().size();
System.out.println("刚连上一个客户端,总共有" + clientSize + "客户端连接成功。");
} @Override
public void onDisconnect(SocketIOClient client) {
Integer clientSize = server.getAllClients().size();
System.out.println("刚离开一个客户端,总共有" + clientSize + "客户端连接成功。");
} @Override
public void onData(SocketIOClient client, String data, AckRequest ackSender)
throws Exception {
System.out.println("刚有一个数据从客户端过来" + data);
ackSender.sendAckData("服务端消息收到!-----");
} }
以上为监听类
package com.ewin.ccr; import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOServer;
import com.ewin.ccr.util.SocketConfig; public class SocketServer { public static void main(String[] args) {
Configuration config = new Configuration();
config.setHostname(SocketConfig.getValue("host"));
config.setPort(Integer.parseInt(SocketConfig.getValue("port")));
SocketIOServer server = new SocketIOServer(config); SocketListener socketListener = new SocketListener(server); //客户端连接上时触发
server.addConnectListener(socketListener); //监听客户端消息
//工单产品执行监控表头数据,只发一次,需要由客户端请求后发送
server.addEventListener("testMessage", String.class, new socketListener()); //客户断连接断开时触发
server.addDisconnectListener(socketListener);
//启动服务
server.start(); // server.stop();
}
}
以上为开启socket服务的类
运行SocketServer这个类
然后进入我们的demo页面,你会看到如下信息
后台会是这样的。
然后我们尝试关闭页面。后台会变成这样。
我们尝试关掉JAVA服务,页面会变成这样。
其实,这还没完,这里不知是BUG,还是什么原因,会有一个问题。
看到页面这个地方没有
现在我们来换一下,发送一个中文的"你好"给后台,我们需要把上面的注释取消,把下面的注释放开,改成这样
然后我们把demo.html页面刷新一下,关掉,再重开(这样是为了使修改的JS生效)
OK,前面没有问题,再看下我们的二个中文字“你好”过去没有。
看到没,后端是乱码,估计这种问题的第一反应,可能绝大数程序员想的跟我一样,转码出了问题,于是各种前后端编码,字符集的检查,但是你会发现,以前出现这种问题时,能用上的转码,切换字符集的招数都用遍了, 这里依然无效。
经过我一天的摸索,得到一个好消息与一个坏消息。
先说坏的,百度有人说是socket.io版本不够新,今天是2017年6月4号,最新版是6月2号的2.0.2版本,我试了一下最新的,问题依然存在。
好消息是我找到了问题的解决办法,但是过于暴力。
看下面这段代码:
跟刚才的本质没有变,只是延迟0.5秒发送消息,我们再次刷新demo.html页面,来看下后台的反应。
看到没,中文传送过来了。
那有人可能就要问了,如果做一个即时通讯之类的,那岂不是每次发送消息都要等上半秒钟,其实不是这样的,经过我多次的测试,只有在连接刚建立完成以后的一小段时间内发送中文才会有这个问题(上面其实是连建立后等了0.5秒发送的消息,实际上测的是延迟0.2秒以上再发送消息 ,后面收到中文的概率已经很大了),后面再发送都不会有这个问题。
html面页与JAVA通过webSocket 通讯的更多相关文章
- Java用WebSocket + tail命令实现Web实时日志
原文:http://blog.csdn.net/xiao__gui/article/details/50041673 在Linux操作系统中,经常需要查看日志文件的实时输出内容,通常会使用tail - ...
- java 实现websocket
最近了解了下websocket和socket这个东西,说不得不来说下为何要使用 WebSocket ,和为何不用http. 为何需要WebSocket ? HTTP 协议是一种无状态的.无连接的.单向 ...
- websocket通讯协议(10版本)简介
前言: 工作中用到了websocket 协议10版本的,英文的协议请看这里: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotoc ...
- Java和WebSocket开发网页聊天室
小编心语:咳咳咳,今天又是聊天室,到现在为止小编已经分享了不下两个了,这一次跟之前的又不大相同,这一次是网页聊天室,具体怎么着,还请各位看官往下看~ Java和WebSocket开发网页聊天室 一.项 ...
- Java 线程间通讯(管道流方式)
一.管道流是JAVA中线程通讯的常用方式之一,基本流程如下: 1)创建管道输出流PipedOutputStream pos和管道输入流PipedInputStream pis 2)将pos和pis匹配 ...
- Java 线程间通讯(共享变量方式)
Java线程间通讯,最常用的方式便是共享变量方式,多个线程共享一个静态变量就可以实现在线程间通讯,但是这需要注意的就是线程同步问题. 一.没考虑线程同步: package com.wyf; publi ...
- 基于Java的WebSocket推送
WebSocket的主动推送 关于消息推送,现在的解决方案如轮询.长连接或者短连接,当然还有其他的一些技术框架,有的是客户端直接去服务端拿数据. 其实推送推送主要讲的是一个推的概念,WebSocket ...
- webSocket通讯
1.使用facebook第三方SRWebSocket进行websocket通讯. pod 'SocketRocket' 2.通讯地址: ws://192.168.1.128:18882/ws 注意:s ...
- java 实现websocket的三种方式
Java中实现websocket常见有以下三种方式: 使用tomcat的websocket实现,需要tomcat 7.x,JEE7的支持. 使用spring的websocket,spring与webs ...
随机推荐
- 各种官网系统镜像文件(Windows 7 ,Windows 10,Ubuntu 18.6,Centos 6.8 ,Centos 7.6 )
在以前的刚进去计算机行业的时候,学的第一件事就是装系统,在网上苦于找不到正版的系统,这些是一直以来,见识的比较稳定的,有些是从官网下载的系统,给大家分享一哈.大家如果有用到其他好的系统,可以给我留言或 ...
- 谈谈MySQL优化原理
说起MySQL的查询优化,相信大家收藏了一堆奇淫技巧:不能使用SELECT *.不使用NULL字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解其背后的工作原 ...
- 46.Linux-创建rc红外遥控平台设备,实现重复功能(2)
上章链接:46.Linux-分析rc红外遥控平台驱动框架,修改内核的NEC解码函数BUG(1) 在上章分析了红外platform_driver后,已经修改bug后,接下来我们自己创建一个红外platf ...
- Netty 系列六(编解码器).
一.概念 网络传输的单位是字节,如何将应用程序的数据转换为字节,以及将字节转换为应用程序的数据,就要说到到我们该篇介绍的编码器和解码器. 将应用程序的数据转换为网络格式,以及将网络格式转换为应用程序的 ...
- 并发之AQS
一.概述 谈到并发,不得不谈ReentrantLock:而谈到ReentrantLock,不得不谈AbstractQueuedSynchronizer(AQS)! 类如其名,抽象的队列式的同步器,AQ ...
- LeNet训练MNIST
jupyter notebook: https://github.com/Penn000/NN/blob/master/notebook/LeNet/LeNet.ipynb LeNet训练MNIST ...
- 【 js 工具 】如何在Github Pages搭建自己写的页面?
最近发现 github 改版了,已没有像原来的 Launch automatic page generator 这样的按钮等,所以我对我的文章也进行了修正,对于新版来说,步骤更加简单了.欢迎享用. - ...
- JS与CSS阻止元素被选中及清除选中的方法总结
有时候,我们希望阻止用户选中我们指定区域的文字或内容. 举个栗子,有时候用户在一个区域执行频繁的点击操作,一不小心傲娇地点多了,就会选中当前区域的内容. 再举个栗子,制作轮播组件的时候,点击下一页,若 ...
- jQuery计算文本宽度和input标签根据输入字符动态自适应宽度的实现
jQuery计算文本宽度的原理是利用html提供的<pre>标签,向dom中动态添加<pre>标签,标签里的内容就是要测试长度的文本,获取完长度之后再删除刚才添加的<pr ...
- js替换字符中的斜杠反斜杠
var reg=/\\|\//g; var a="a\a\\a/b" alert(a.replace(reg,"-"));