公司项目须要,了解了下眼下几种支持WebSocket的框架。曾经用jWebSocket做过一些项目。相对来说。改jWebSocket的源代码略复杂,也不是一天两天能搞定的。

一调研才发现,如今非常多主流的web框架都已经開始支持WebSocket了,不得不感慨时间太快,科技进步太快,在微策略的几年真的荒废了。不多说,先记录下今天的研究。

Tomcat:

J2EE以下用的最多的容器应该就是tomcat了。说到tomcat对WebSocket的支持,不得不先提一下,眼下的WebSocket协议已经经过了好几代的演变。不同浏览器对此协议的支持程度也不同。因此,假设作为server。最理想的是支持尽可能多的WebSocket协议版本号。

tomcat8真正支持jsr-356(包括对websocket的支持)。 tomcat7支持部分版本号的websocket实现不兼容jsr-356。因此,能用tomcat8的话,还是尽量用。

代码实现相当简单,下面是一个列子,仅仅须要tomcat8的基本库,不须要其它依赖。

import java.io.IOException;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/websocket")
public class WebSocketTest { @OnMessage
public void onMessage(String message, Session session) throws IOException,
InterruptedException {
// Print the client message for testing purposes
System.out.println("Received: " + message);
// Send the first message to the client
session.getBasicRemote().sendText("This is the first server message");
// Send 3 messages to the client every 5 seconds
int sentMessages = 0;
while (sentMessages < 3) {
Thread.sleep(5000);
session.getBasicRemote().sendText("This is an intermediate server message. Count: " + sentMessages);
sentMessages++;
}
// Send a final message to the client
session.getBasicRemote().sendText("This is the last server message");
} @OnOpen
public void onOpen() {
System.out.println("Client connected");
} @OnClose
public void onClose() {
System.out.println("Connection closed");
}
}

Jetty:

Jetty和Tomcat一样,也是一个Servlet的容器。假设说不同之处,那么最大的不同应该是Tomcat採用的是BIO处理方式,也就是说一个request会用一个线程去处理,即使是WebSocket这样的长连接,也是会独立开一个线程。

作为一个普通的Webserver,tomcat能够轻松应对耗时比較短的Request/Response。可是假设换成是长连接的WebSocket。那麻烦就来了,对于上万用户的聊天和推送,总不能开上万个线程去处理吧。此时,Jetty的性能就体现出来了。Jetty採用的是NIO,一个线程能够处理多个WebSocket的长链接,假设你的需求是大量耗时比較长的request或者大量长连接,那么建议採用Jetty。

Jetty对WebSocket的实现有点绕,Servlet不再是继承原来的HttpServlet。而是继承WebSocketServlet。此处要注意导入jetty-util.jar和jetty-websocket.jar两个包,否则可能会有class not found错误。

ReverseAjaxServlet.java:

import java.io.IOException;
import java.util.Date;
import java.util.Random; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.codehaus.jettison.json.JSONArray;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketServlet; /**
* @author Mathieu Carbou (mathieu.carbou@gmail.com)
*/
public final class ReverseAjaxServlet extends WebSocketServlet { private final Endpoints endpoints = new Endpoints();
private final Random random = new Random();
private final Thread generator = new Thread("Event generator") {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(random.nextInt(5000));
endpoints.broadcast(new JSONArray().put("At " + new Date()).toString());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}; @Override
public void init() throws ServletException {
super.init();
generator.start();
} @Override
public void destroy() {
generator.interrupt();
super.destroy();
} @Override
public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
return endpoints.newEndpoint();
} @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().write("11111");
}
}

Endpoints.java:

package com.cn.test.chapter2.websocket;

import org.eclipse.jetty.websocket.WebSocket;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue; /**
* @author Mathieu Carbou (mathieu.carbou@gmail.com)
*/
final class Endpoints {
private final Queue<Endpoint> endpoints = new ConcurrentLinkedQueue<Endpoint>(); void broadcast(String data) {
// for (Endpoint endpoint : endpoints) {
// endpoint.onMessage(data);
// }
} void offer(Endpoint endpoint) {
endpoints.offer(endpoint);
} void remove(Endpoint endpoint) {
endpoints.remove(endpoint);
} public WebSocket newEndpoint() {
return new Endpoint(this);
}
}

Endpoint.java

import java.io.IOException;
import java.util.concurrent.ConcurrentLinkedQueue; import org.codehaus.jettison.json.JSONArray;
import org.eclipse.jetty.websocket.WebSocket; /**
* @author Mathieu Carbou (mathieu.carbou@gmail.com)
*/
class Endpoint implements WebSocket.OnTextMessage { protected Connection _connection; private Endpoints endpoints; private static int clientCounter = 0;
private int clientId = clientCounter++; public Endpoint(Endpoints endpoints) {
this.setEndpoints(endpoints);
} @Override
public void onClose(int code, String message) {
System.out.println("Client disconnected"); this.endpoints.remove(this);
} @Override
public void onOpen(Connection connection) {
System.out.println("Client connected");
_connection = connection;
try {
this._connection.sendMessage(new JSONArray().put("ClientID = " + clientId).toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
endpoints.offer(this);
} @Override
public void onMessage(final String data) {
System.out.println("Received data: " + data);
this.endpoints.broadcast(data);
} public Endpoints getEndpoints() {
return endpoints;
} public void setEndpoints(Endpoints endpoints) {
this.endpoints = endpoints;
}
}

辅助工具:

在编写server最麻烦的是要写相应的client来測试,还好Chrome为我们攻克了这个问题。下载Chrome插件WebSocket Clinet能够轻松地和server建立连接,发送消息到server。

Tomcat和Jetty对WebSocket的支持的更多相关文章

  1. Undertow,Tomcat和Jetty服务器配置详解与性能测试

    undertow,jetty和tomcat可以说是javaweb项目当下最火的三款服务器,tomcat是apache下的一款重量级的服务器,不用多说历史悠久,经得起实践的考验.然而:当下微服务兴起,s ...

  2. Jmeter中Websocket协议支持包的使用

    Jmeter中Websocket协议支持包的使用(转) 参考的来源是国外一篇文章,已经整理成pdf格式(http://yunpan.cn/cFzwiyeQDKdh3 (提取码:9bcf)) 转自:ht ...

  3. jmeter关联Websocket包支持

    消息文本发送内容采用的是websocket方式进行消息握手的,一次使用到WEBSOCKET包支持 对于它的介绍和使用如下: 一.首先,我们需要准备Jmeter的WebSocket协议的支持插件:JMe ...

  4. Tomcat学习总结(7)——Tomcat与Jetty比较

    Jetty 基本架构 Jetty目前的是一个比较被看好的 Servlet 引擎,它的架构比较简单,也是一个可扩展性和非常灵活的应用服务器. 它有一个基本数据模型,这个数据模型就是 Handler(处理 ...

  5. tomcat与jetty的区别

    转载自:https://www.cnblogs.com/fengli9998/p/7247559.html Jetty和Tomcat为目前全球范围内最著名的两款开源的webserver/servlet ...

  6. Web服务(Apache、Nginx、Tomcat、Jetty)与应用(LAMP、CMS-WordPress&Ghost、Jenkins、Gitlab)

    Web服务和应用是目前信息技术领域的热门技术.如何使用Docker来运行常见的Web服务器(包括Apache.Nginx.Tomcat等),以及一些常用应用(LAMP.CMS等).包括具体的镜像构建方 ...

  7. 一.配置简单的嵌入式tomcat和jetty

    我们写了一个web应用,打成war包后,就需要找一个server来部署.对于我们的实际应用,我们基本没必要自己再写一个嵌入式的server.接下来两篇文章只是以钻研的心态来学习一下嵌入式tomcat和 ...

  8. Maven配置tomcat和jetty插件来运行项目

    针对eclipse中的Run on Server有些情况下并不是那么好操作,比如配置maven下的springmvc插件,如果使用此方法运行会很容易出现组件缺少导致错误出现一大堆的问题. 那么针对这种 ...

  9. Spring Boot 内嵌容器 Tomcat / Undertow / Jetty 优雅停机实现

    Spring Boot 内嵌容器 Tomcat / Undertow / Jetty 优雅停机实现 Anoyi 精讲JAVA 精讲JAVA 微信号 toooooooozi 功能介绍 讲解java深层次 ...

随机推荐

  1. vue 中scroll事件不触发问题

    在vue项目中需要监听滚动条滚动的位置,结果写了scroll监听事件就是不生效,最后查资料发现是页面有样式设置了over-flow:scroll,去掉之后完美解决.(页面样式中存在over-flow: ...

  2. get、post、put、delete

    form表单有两种提交方式,get和post,get没有请求体, 但是有查询字符串参数拼接在url后面,post有请求体,表单内容对用户不可见. 1.form表单以get请求提交, 2.from表单以 ...

  3. java 图片合成文字或者awt包下的对话框引入自定义字体库

    成就卡图片字体问题:1.下载 xxx.ttf 文件2.mkdir /usr/local/jdk1.6.0_11/jre/lib/fonts/fallback.     在jre/lib/fonts 下 ...

  4. linux常用过滤日志命令

    #过滤nginx访问日志awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr -k1 | head -n 10 ...

  5. 自动化测试如何解析excel文件?

    前言 自动化测试中我们存放数据无非是使用文件或者数据库,那么文件可以是csv,xlsx,xml,甚至是txt文件,通常excel文件往往是我们的首选,无论是编写测试用例还是存放测试数据,excel都是 ...

  6. 在VS中如何更换项目名称

    我们常常在建立项目的时候就必须输入一个项目名称,有的时候我们就随意的起了一个名称,可是到后面想到了一个更好的项目名我们就想把项目名称改过来,但VS并不那么智能,我们不能简单的将项目对应的解决方案SLN ...

  7. 大数据学习——hdfs集群启动

    第一种方式: 1 格式化namecode(是对namecode进行格式化) hdfs namenode -format(或者是hadoop namenode -format) 进入 cd /root/ ...

  8. jmeter 断言-各种分类讲解

    jmeter中有个元件叫做断言(Assertion),它的作用和loadrunner中的检查点类似: 用于检查测试中得到的响应数据等是否符合预期,用以保证性能测试过程中的数据交互与预期一致. 使用断言 ...

  9. hust训练赛20160330--B - 又见LKity

    Problem 2122 又见LKity Time Limit: 1000 mSec Memory Limit : 32768 KB  Problem Description 嗨!大家好,在Templ ...

  10. Auto-Scaling Web Applications in Clouds: A Taxonomy and Survey读书笔记

    这篇文章是发在2018年CSUR上的一篇文章,主要是讲虚拟机上web应用的auto-scaling技术的分类 近年来许多web 应用服务商将他们的应用迁移到云数据中心,为什么要迁移到云上呢?其中一个重 ...