最近了解了下websocket和socket这个东西,说不得不来说下为何要使用 WebSocket ,和为何不用http。

为何需要WebSocket ?

HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理。

这种通信模型有一个弊端:HTTP 协议无法实现服务器主动向客户端发起消息。

这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。大多数 Web 应用程序将通过频繁的异步JavaScript和XML(AJAX)请求实现长轮询。轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。

因此,工程师们一直在思考,有没有更好的方法。WebSocket 就是这样发明的。WebSocket 连接允许客户端和服务器之间进行全双工通信,以便任一方都可以通过建立的连接将数据推送到另一端。WebSocket 只需要建立一次连接,就可以一直保持连接状态。这相比于轮询方式的不停建立连接显然效率要大大提高。

下面来一个例子,实现web客户端和服务器端的连续通讯。

客户端页面index.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Java后端WebSocket的Tomcat实现</title>
  5. </head>
  6. <body>
  7. Welcome<br/><input id="text" type="text"/>
  8. <button onclick="send()">发送消息</button>
  9. <hr/>
  10. <button onclick="closeWebSocket()">关闭WebSocket连接</button>
  11. <hr/>
  12. <div id="message"></div>
  13. </body>
  14.  
  15. <script type="text/javascript">
  16. var websocket = null;
  17. //判断当前浏览器是否支持WebSocket
  18. if ('WebSocket' in window) {
  19. websocket = new WebSocket("ws://localhost:8080/Testwebsocket/websocket");
  20. }
  21. else {
  22. alert('当前浏览器 Not support websocket')
  23. }
  24.  
  25. //连接发生错误的回调方法
  26. websocket.onerror = function () {
  27. setMessageInnerHTML("WebSocket连接发生错误");
  28. };
  29.  
  30. //连接成功建立的回调方法
  31. websocket.onopen = function () {
  32. setMessageInnerHTML("WebSocket连接成功");
  33. }
  34.  
  35. //接收到消息的回调方法
  36. websocket.onmessage = function (event) {
  37. setMessageInnerHTML(event.data);
  38. }
  39.  
  40. //连接关闭的回调方法
  41. websocket.onclose = function () {
  42. setMessageInnerHTML("WebSocket连接关闭");
  43. }
  44.  
  45. //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
  46. window.onbeforeunload = function () {
  47. closeWebSocket();
  48. }
  49.  
  50. //将消息显示在网页上
  51. function setMessageInnerHTML(innerHTML) {
  52. document.getElementById('message').innerHTML += innerHTML + '<br/>';
  53. }
  54.  
  55. //关闭WebSocket连接
  56. function closeWebSocket() {
  57. websocket.close();
  58. }
  59.  
  60. //发送消息
  61. function send() {
  62. var message = document.getElementById('text').value;
  63. websocket.send(message);
  64. }
  65. </script>
  66. </html>

 服务器端:服务器端的很简单。

1.创建一个web 的maven项目

2.引入一个包

  1. <!-- websocket -->
  2. <dependency>
  3. <groupId>javax</groupId>
  4. <artifactId>javaee-api</artifactId>
  5. <version>7.0</version>
  6. <scope>provided</scope>
  7. </dependency>

3.创建一个类。

  1. package com.sun.web.handler;
  2.  
  3. import java.io.IOException;
  4. import java.util.concurrent.CopyOnWriteArraySet;
  5.  
  6. import javax.websocket.*;
  7. import javax.websocket.server.ServerEndpoint;
  8.  
  9. /**
  10. * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
  11. * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
  12. */
  13. @ServerEndpoint("/websocket")
  14. public class WebSocketTest {
  15. //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
  16. private static int onlineCount = 0;
  17.  
  18. //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
  19. private static CopyOnWriteArraySet<WebSocketTest> webSocketSet = new CopyOnWriteArraySet<WebSocketTest>();
  20.  
  21. //与某个客户端的连接会话,需要通过它来给客户端发送数据
  22. private Session session;
  23.  
  24. /**
  25. * 连接建立成功调用的方法
  26. * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
  27. */
  28. @OnOpen
  29. public void onOpen(Session session){
  30. this.session = session;
  31. webSocketSet.add(this); //加入set中
  32. addOnlineCount(); //在线数加1
  33. System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
  34. }
  35.  
  36. /**
  37. * 连接关闭调用的方法
  38. */
  39. @OnClose
  40. public void onClose(){
  41. webSocketSet.remove(this); //从set中删除
  42. subOnlineCount(); //在线数减1
  43. System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
  44. }
  45.  
  46. /**
  47. * 收到客户端消息后调用的方法
  48. * @param message 客户端发送过来的消息
  49. * @param session 可选的参数
  50. */
  51. @OnMessage
  52. public void onMessage(String message, Session session) {
  53. System.out.println("来自客户端的消息:" + message);
  54. //群发消息
  55. for(WebSocketTest item: webSocketSet){
  56. try {
  57. item.sendMessage(message);
  58. } catch (IOException e) {
  59. e.printStackTrace();
  60. continue;
  61. }
  62. }
  63. }
  64.  
  65. /**
  66. * 发生错误时调用
  67. * @param session
  68. * @param error
  69. */
  70. @OnError
  71. public void onError(Session session, Throwable error){
  72. System.out.println("发生错误");
  73. error.printStackTrace();
  74. }
  75.  
  76. /**
  77. * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
  78. * @param message
  79. * @throws IOException
  80. */
  81. public void sendMessage(String message) throws IOException{
  82. this.session.getBasicRemote().sendText(message);
  83. //this.session.getAsyncRemote().sendText(message);
  84. }
  85.  
  86. public static synchronized int getOnlineCount() {
  87. return onlineCount;
  88. }
  89.  
  90. public static synchronized void addOnlineCount() {
  91. WebSocketTest.onlineCount++;
  92. }
  93.  
  94. public static synchronized void subOnlineCount() {
  95. WebSocketTest.onlineCount--;
  96. }
  97. }

4.以上三步就OK了,然后就是用tomcat运行就行了。

效果如图:

java 实现websocket的更多相关文章

  1. Java和WebSocket开发网页聊天室

    小编心语:咳咳咳,今天又是聊天室,到现在为止小编已经分享了不下两个了,这一次跟之前的又不大相同,这一次是网页聊天室,具体怎么着,还请各位看官往下看~ Java和WebSocket开发网页聊天室 一.项 ...

  2. Java用WebSocket + tail命令实现Web实时日志

    原文:http://blog.csdn.net/xiao__gui/article/details/50041673 在Linux操作系统中,经常需要查看日志文件的实时输出内容,通常会使用tail - ...

  3. 基于Java的WebSocket推送

    WebSocket的主动推送 关于消息推送,现在的解决方案如轮询.长连接或者短连接,当然还有其他的一些技术框架,有的是客户端直接去服务端拿数据. 其实推送推送主要讲的是一个推的概念,WebSocket ...

  4. java 实现websocket的三种方式

    Java中实现websocket常见有以下三种方式: 使用tomcat的websocket实现,需要tomcat 7.x,JEE7的支持. 使用spring的websocket,spring与webs ...

  5. java集成WebSocket向指定用户发送消息

    一.WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通 ...

  6. Java后端WebSocket的Tomcat实现(转载)

    一.WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通 ...

  7. js使用WebSocket,java使用WebSocket

    js使用WebSocket,java使用WebSocket 创建java服务端代码 import java.net.InetSocketAddress; import org.java_websock ...

  8. Java实现WebSocket服务

    一.使用Tomcat提供的WebSocket库  Java可以使用Tomcat提供的WebSocket库接口实现WebSocket服务,代码编写也非常的简单.现在的H5联网游戏基本上都是使用WebSo ...

  9. Java Springboot webSocket简单实现,调接口推送消息到客户端socket

    Java Springboot webSocket简单实现,调接口推送消息到客户端socket 后台一般作为webSocket服务器,前台作为client.真实场景可能是后台程序在运行时(满足一定条件 ...

随机推荐

  1. css文字效果(文字剪贴蒙版,text-shodow的应用,文字排版等…)

    .katex { display: inline-block; text-align: initial; } .katex { font-family: Consolas, Inconsolata, ...

  2. go语言学习-goroutine

    o 语言有一个很重要的特性就是 goroutine, 我们可以使用 goroutine 结合 channel 来开发并发程序. 并发程序指的是可以同时运行多个任务的程序,这里的同时运行并不一定指的是同 ...

  3. 幕布V1.1.9最新版漏洞集合

    0X00 前言 幕布本人最早接触是在P神的知识星球里面看到P神推荐的,后来下了个用着还挺好用. 之前一直都放一些零零散散的笔记,最近整理的时候,一时兴起,本着漏洞源于生活的态度,遂对幕布的安全性做了些 ...

  4. zip&ftp命令

    zip: C:\Users\IBM_ADMIN>zip -09r Oracle.zip ./Oracle/* C:\Users\IBM_ADMIN>ftp ftp> open adm ...

  5. Lakeshore 中文开发界面,示例项目,飞机大战 等 Lakeshore Chinese development interface, sample project, aircraft war, etc

    Lakeshore 中文开发界面,示例项目,飞机大战 等 Lakeshore Chinese development interface, sample project, aircraft war, ...

  6. c#textBox控件限制只允许输入数字及小数点

    在textboxd的事件中的 KeyPress 事件,这样双击进入代码:输入以下代码 即可 //判断按键是不是要输入的类型. || () && ( && () e.Ha ...

  7. loj#2574. 「TJOI2018」智力竞赛 (路径覆盖)

    目录 题目链接 题解 代码 题目链接 loj#2574. 「TJOI2018」智力竞赛 题解 就是求可重路径覆盖之后最大化剩余点的最小权值 二分答案后就是一个可重复路径覆盖 处理出可达点做二分图匹配就 ...

  8. HDU.1529.Cashier Employment(差分约束 最长路SPFA)

    题目链接 \(Description\) 给定一天24h 每小时需要的员工数量Ri,有n个员工,已知每个员工开始工作的时间ti(ti∈[0,23]),每个员工会连续工作8h. 问能否满足一天的需求.若 ...

  9. C#中使用 SendMessage 向非顶端窗体发送组合键

    开门见山,不废话了, 直接举例说明一下: 比如发送ALT + F 以下是 用spy++截取的消息内容 <00001> 000310DC P WM_SYSKEYDOWN nVirtKey:V ...

  10. dhtmlxtree 节点 展开收缩:新增了直接点 文本内容 也 实现了 展开收缩 功能(并记住了展开、收缩状态)

    dhtmlxtree 节点 展开收缩通常情况我们按 +- 就实现了 展开收缩 功能,为了方便我们新增了直接点 文本内容 也 实现了 展开收缩 功能(并记住了展开.收缩状态) tree = new dh ...