`

反向 Ajax,第 3 部分: Web 服务器和 Socket.IO

阅读更多

简介

现今,用户都期待能够通过 Web 访问快速的动态访问应用。本 系列文章 向您展示如何使用 Reverse Ajax 技术来开发事件驱动的 Web 应用程序。反向 Ajax,第 1 部分:Comet 简介 介绍了 Reverse Ajax、轮询、流、Comet 和长轮询。在您了解了如何通过 HTTP 使用 Comet 之后,就会发现长轮询是可靠地实现 Reverse Ajax 的最佳方式,因为目前所有浏览器都提供了这方面的支持。反向 Ajax,第 2 部分:WebSockets 展示了如何使用 WebSocket 实现 Reverse Ajax。代码示例有助于说明 WebSocket、FlashSocket、服务器端的约束、请求范围内的服务和暂停历时长久的请求。

本文将深入研究如何在不同 Web 容器和 API 的 Web 应用程序(Servlet 3.0 和 Jetty Continuation)中使用 Comet 和 WebSocket。了解如何通过抽象库(如 Socket.IO)透明地使用 Comet 和 WebSocket。Socket.IO 使用功能检测来决定是否将通过 WebSocket、AJAX 长轮询或 Flash 等来创建连接。

您可以 下载本文使用的源代码

先决条件

在理想情况下,要最大限度地充分利用本文,则应该了解 JavaScript 和 Java。本文创建的示例是使用 Google Guice 构建的。Google Guice 是用 Java 编写的依赖项注入框架。要理解本文内容,则需要熟悉依赖项注入框架的概念,比如 Guice、Spring 或 Pico。

要运行本文中的示例,还需要使用最新版的 Maven 和 JDK (请参阅 参考资料)。

 

Comet 和 WebSocket 的服务器解决方案

您在 反向 Ajax,第 1 部分:Comet 简介 中应该已经了解到,Comet(长轮询或流)要求服务器在潜在的长延迟后能够暂停、重启或完成一个请求。反向 Ajax,第 2 部分:WebSockets 描述了服务器需要如何使用非阻塞 I/O 特性来处理一些连接,以及它们如何仅使用线程为请求提供服务(每请求线程模型)。您应该还了解到,WebSocket 的使用取决于服务器,并非所有的服务器都支持 WebSocket。

这一节将向您展示如何在 Jetty、Tomcat 和 Grizzly Web 服务器上使用 Comet 和 WebSocket(如果可以)。本文所提供的 源代码 包含了一个在 Jetty 和 Tomcat 上运行的简单聊天 Web 应用程序样例。本章节还将讨论支持 API 的下列应用服务器:Jboss、Glassfish 和 WebSphere。

Jetty

Jetty 是一个 Web 服务器,它支持 Java Servlet 规范 3.0、WebSocket 和其他的集成规范。Jetty 具有以下特征:

  • 强大而又灵活
  • 易于嵌入
  • 支持虚拟主机、会话集群和一些可以轻易通过 Java 代码进行配置的特性
  • 适用于 Google App Engine 的托管服务

核心的 Jetty 项目是由 Eclipse Foundation 管理。

自从版本 6 开始,Jetty 包含了一个异步 API,称为 Jetty Continuation,它可以充许暂停某个请求,稍后再重新开始该请求。表 1 显示了 Jetty 主要版本所支持的规范和 API 的图表。

表 1. Jetty 版本和支持
支持 Jetty 6 Jetty 7 Jetty 8
非阻塞 I/O X X X
Servlet 2.5 X X X
Servlet 3.0   X X
Jetty Continuation (Comet) X X X
WebSocket   X X

要通过 Comet 实现 Reverse Ajax ,可以使用 Jetty 所提供的 Continuation API,如下所示 清单 1:

清单 1. 用于 Comet 的 Jetty Continuation API
// Pausing a request from a servlet's method (get, post, ...):

protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
        throws ServletException, IOException { 

Continuation continuation = ContinuationSupport.getContinuation(req); 
// optionally set a timeout to avoid suspending requests for too long 
continuation.setTimeout(0); 
// suspend the request 
continuation.suspend(); 
// then hold a reference for future usage from another thread 
continuations.offer(continuation); 

}

// Then, from another thread which wants to send an event to the client:

while (!continuations.isEmpty()) { 
    Continuation continuation = continuations.poll(); 
    HttpServletResponse response = 
        (HttpServletResponse) continuation.getServletResponse(); 
    // write to the response 
    continuation.complete(); 
}

完整的 Web 应用程序可在本文所附的 源代码 中找到。Jetty Continuation 存放在 JAR 文件中。您必须将此 JAR 文件放在 Web 应用程序的 WEB-INF/lib 文件夹中,以便能够使用 Jetty 的 Comet 特性。Jetty Continuation 也可以在 Jetty 6、Jetty 7 和 Jetty 8 上使用。

从 Jetty 7 开始,您还可以使用 WebSocket 特性。将 Jetty 的 WebSocket JAR 文件放入 Web 应用程序的 WEB-INF/lib 文件夹中,以便获得访问 Jetty 的 WebSocket API 的访问权,如 清单 2 中所示:

清单 2. Jetty 的 WebSocket API
// Implement the  doWebSocketConnect and returns an implementation of
//  WebSocket:

public final class ReverseAjaxServlet extends WebSocketServlet { 
    @Override 
    protected WebSocket doWebSocketConnect(HttpServletRequest request,
                                           String protocol) { 
        return [...] 
    } 
}

// Sample implementation of  WebSocket:

class Endpoint implements WebSocket { 
    Outbound outbound; 
    public void onConnect(Outbound outbound) { 
        this.outbound = outbound;    
    } 
    public void onMessage(byte opcode, String data) { 
        outbound.sendMessage("Echo: " + data);
        if("close".equals(data)) 
             outbound.disconnect();
    } 
    public void onFragment(boolean more, byte opcode, 
                           byte[] data, int offset, int length) { 
    } 
    public void onMessage(byte opcode, byte[] data, 
                          int offset, int length) { 
        onMessage(opcode, new String(data, offset, length)); 
    } 
    public void onDisconnect() { 
        outbound = null; 
    } 
}

可下载 源代码 中的 jetty-websocket 文件夹提供了一个聊天示例,它演示了如何使用 Jetty 提供的 WebSocket API。

Tomcat

Tomcat 可能是最广为人知的 Web 服务器。人们使用它已经很多年了,并且它已作为 Web 容器集成到早期版本的 Jboss 应用服务器中。Tomcat 还可以用作 servlet 规范的参考实现。servlet API 2.5 开始停用 Tomcat,人们开始关注基于非阻塞 I/O(如 Jetty)的替代物。表 2 显示了 Tomcat 两个最新版本支持的规范和 API。

表 2. Tomcat 支持
支持 Tomcat 6 Tomcat 7
非阻塞 I/O X X
Servlet 2.5 X X
Servlet 3.0   X
Advanced I/O (Comet) X X
WebSocket    

如 表 2 中所示,Tomcat 并不支持 WebSocket;它使用一个与 Jetty Continuation 等效的对等物(叫 Advanced I/O)来支持 Comet。Advanced I/O 是一个包装 NIO 的低级包装器,比优秀的 API 更能促进 Comet 的使用。使用此 API 的应用程序示例相对贪乏,没有几个。清单 3 显示了在聊天 Web 应用程序中用于挂起请求和恢复使用请求的 servlet 示例。您可以在本文里的 源代码 中找到完整的 Web 应用程序。

清单 3. Comet 的 Tomcat API
public final class ChatServlet extends HttpServlet 
                               implements CometProcessor { 

    private final BlockingQueue<CometEvent> events = 
         new LinkedBlockingQueue<CometEvent>(); 

    public void event(CometEvent evt) 
        throws IOException, ServletException { 

        HttpServletRequest request = evt.getHttpServletRequest(); 
        String user = 
            (String) request.getSession().getAttribute("user"); 
        switch (evt.getEventType()) { 
            case BEGIN: { 
                if ("GET".equals(request.getMethod())) { 
                    evt.setTimeout(Integer.MAX_VALUE); 
                    events.offer(evt); 
                } else { 
                    String message = request.getParameter("message"); 
                    if ("/disconnect".equals(message)) { 
                        broadcast(user + " disconnected"); 
                        request.getSession().removeAttribute("user"); 
                        events.remove(evt); 
                    } else if (message != null) { 
                        broadcast("[" + user + "]" + message); 
                    } 
                    evt.close(); 
                } 
            } 
        } 
    } 

    void broadcast(String message) throws IOException { 
        Queue<CometEvent> q = new LinkedList<CometEvent>(); 
        events.drainTo(q); 
        while (!q.isEmpty()) { 
            CometEvent event = q.poll(); 
            HttpServletResponse resp = event.getHttpServletResponse();
            resp.setStatus(HttpServletResponse.SC_OK);
            resp.setContentType("text/html");
            resp.getWriter().write(message);
            event.close(); 
        } 
    } 
}

在 Tomcat 里,异步 servlet 必须实现一个 CometProcessor。对于异步 servlet,Tomcat 并不调用标准 HTTP 方法(doGet 和 doPost 等)。相反,会向 event(CometdEvent) 方法发送一个事件。在请求到达时,该示例会查看是否为了挂起该请求而使用了一个 GET 方法;不必调用evt.close() 。如果调用的是一个 POST 方法,则表示用户发送了一个消息,该消息将传播至其他 CometEvent,并且可以调用evt.close() 来完成请求的传送。在用户端,广播会让所有的长轮询请求来完成消息发送,并且会立即发送另一个长轮询请求来接收下一个事件。

Grizzly 和 Glassfish

Grizzly 并不是一个 Web 容器,它更像是一个帮助开发人员构建可伸缩性应用程序的 NIO 框架。它发展为 Glassfish 项目的一部分,但也可以单独或嵌套使用它。Grizzly 提供了充当 HTTP/HTTPS 服务器的部件,还为 Bayeux Protocol、Servlet、HttpService OSGi 和 Comet 等提供部件。Grizzly 支持 WebSocket,并且可以在 Glassfish 中使用它来支持 Comet 和 WebSocket。

Glassfish(Oracle 的应用服务器)是 J2EE 6 规范的参考实现。Glassfish 是一个完整的套件(像 WebSphere 和 Jboss 一样),它用 Grizzly 来支持 NIO、WebSocket 和 Comet。它的模块架构(基于 OSGI)使得更改部件变得非常灵活。表 3 显示了 Glassfish 对 Comet 和 WebSocket 的支持。

表 3. Glassfish 支持
支持 Glassfish 2 Glassfish 3
非阻塞 I/O X X
Servlet 2.5 X X
Servlet 3.0   X
Comet X X
WebSocket   X

Grizzly 的使用并不繁琐,可以在 Java 代码中嵌套使用或直接使用它。人们普遍将它用作一个框架,用它来支持可以嵌套在大型应用程序(如 Glassfish)中的 Comet 和 WebSocket,这提供了 Web 部署功能和 Servlet 规范 API。

查看 参考资料 中关于 Grizzly 或 Glassfish 中的 WebSocket 和 Comet 示例的链接。因为 Glassfish 使用了 Grizzly,所以两个示例都有效。WebSocket API 与Jetty 中的非常相似,但是 Comet API 更复杂一些。

Jboss

Jboss 是构建于 Tomcat 之上的应用服务器。从版本 5 起,它就开始支持 Comet 和 NIO。Jboss 7 还在开发中,但下面的 表 4 中包含该版本。

表 4. Jboss 支持
支持 Jboss 5 Jboss 6 Jboss 7
非阻塞 I/O X X X
Servlet 2.5 X X X
Servlet 3.0   X X
Comet X X X
WebSocket      

WebSphere

WebSphere 是一个 IBM 应用服务器。WebSphere V8(参阅 参考资料,阅读相关声明)添加了对 Servlet 3 API(包括 Comet 的标准化异步 API)的支持。

表 5. WebSphere 支持
支持 WebSphere 8
非阻塞 I/O X
Servlet 2.5 X
Servlet 3.0 X
Comet X
WebSocket  
 

使用通用 API 会怎样?

每个服务器都自带了用于 Comet 和 WebSocket 的本机 API 。正如您所猜测的,编写一个便携版的 Web 应用程序会非常困难。Servlet 3.0 Specification 包含挂起请求并稍后重新使用请求的其他方法,并充许所有支持 Servlet 3.0 Specification 的 Web 容器支持 Comet 长轮询请求。

Jetty 团队提供了一个名叫 Jetty Continuation 的库,该库独立于 Jetty 容器。Jetty Continuation 库可以智能地检测容器或规范是否可用。如果在 Jetty 服务器上运行,则会使用本机 Jetty API 。如果在支持 Servlet 3.0 规范的容器上运行,则会使用通用的 API。否则会使用不可伸缩的实现。

关于 WebSocket,Java 中没有相关的标准,因此,如果您想要使用 WebSocket,则需要在 Web 应用程序中使用容器供应商 API 。

表 6 概括了各种服务器支持的技术

表 6. 服务器支持的技术
容器 Comet WebSocket
Jetty 6 Jetty Continuation N/A
Jetty 7 Servlet 3.0
Jetty Continuation
Native Jetty API
Jetty 8 Servlet 3.0 
Jetty Continuation
Native Jetty API
Tomcat 6 Advanced I/O N/A
Tomcat 7 Servlet 3.0
Advanced I/O
Jetty Continuation
N/A
Glassfish 2 Native Grizzly API N/A
Glassfish 3 Servlet 3.0
本机 Grizzly API
Jetty Continuations
本机 Grizzly API
Jboss 5 本机 Jboss API N/A
Jboss 6 Servlet 3.0 
本机 Jboss API 
Jetty Continuation 
N/A
Jboss 7 Servlet 3.0
本机 Jboss API
Jetty Continuations
N/A
WebSphere 8 Servlet 3.0
Jetty Continuation
N/A

关于 WebSocket, 除了使用容器 API ,没有其他的明确方案。至于 Comet,支持 Servlet 3.0 Specification 的所有容器都支持 Comet。Jetty Continuation 的优势是它在所有的这些容器上都提供了对 Comet 的支持。因此,一些 Reverse Ajax 库(在 下一节 和 本 系列 文章中的下一篇文章中会讨论它)都在对其服务器端 API 使用 Jetty Continuation。

Jetty Continuation API 在本文的 Jetty 示例 中曾描述过。Servlet 3.0 Specification 在本系列 第 1 部分:Comet 简介 的两个 Comet 示例中使用和描述过。

 

抽象库

考虑到所有主要的 API(Servlet 3.0 和 Jetty Continuation)、服务器端的所有本机支持以及在客户端实现 Reverse Ajax 的两种主要方法(Comet 和 WebSocket),编写您自己的 JavaScript 和 Java 代码以便将它们连接在一起会非常困难。您还必须考虑超时、连接故障、确认、排序和缓冲等因素。

本文的其余部分将向您介绍 Socket.IO。本 系列 的第 4 部分将探讨 Atmosphere 和 CometD。这三个库均为开源库,它们都支持在许多服务器上使用 Comet 和 WebSocket。

Socket.IO

Socket.IO 是一个 JavaScript 客户端库,可提供一个与 WebSocket 类似的 API,用该 API 连接到远程服务器,以便异步发送和接收消息。通过提供通用 API,Socket.IO 可支持多种传输:WebSocket、Flash Sockets、长轮询、流、forever Iframes 和 JSONP 轮询。Socket.IO 检测浏览器功能并尝试选择可用的最佳传输。Socket.IO 库几乎与所有的浏览器(包括旧版浏览器,如 IE 5.5)以及移动浏览器都兼容。它还提供了心跳、超时、断开连接和错误处理等功能。

Socket.IO 网站(参阅 参考资料)详细描述了库的工作原理以及使用哪种浏览器和 Reverse Ajax 技术。基本上,Socket.IO 使用一种可以使客户端库与服务器端的端点通信的通信协议,以便能够读懂 Socket.IO 协议。Socket.IO 最初是为 Node JS 开发的,它使用一个 JavaScript 引擎来构建快速服务器。许多项目都支持其他语言,其中包括 Java。

清单 4 显示了一个在客户端使用 Socket.IO JavaScript 库的示例。Socket.IO 网站中包含一些文档和示例。

清单 4. Socket.IO 客户端库的使用
var socket = new io.Socket(document.domain, { 
    resource: 'chat' 
}); 
socket.on('connect', function() { 
    // Socket.IO is connected
}); 
socket.on('disconnect', function(disconnectReason, errorMessage) { 
    // Socket.IO disconnected
}); 
socket.on('message', function(mtype, data, error) { 
    // The server sent an event
});

// Now that the handlers are defined, establish the connection:
socket.connect();

要使用 Socket.IO JavaScript 库,则需要一个称为 Socket.IO Java 的相应 Java 部件(参阅 参考资料)。该项目最初由 Apache Wave 团队创建,创建于推出 WebSocket 之前,可利用该项目为 Reverse Ajax 提供支持。Socket.IO Java 是 Ovea(一家专门从事事件驱动 Web 开发的公司)的分支,由 Ovea 维护,后来遭到遗弃。由于有多种传输方式,所以开发后端来支持 Socket.IO 客户端库非常复杂。本系列的第 4 部分将展示如何支持客户端库中的许多传输,这种支持并不是获得更好的可伸缩性和浏览器支持所必需的,因为有长轮询和 WebSocket 就已经足够。在 WebSocket 尚未发布的时候,Socket.IO 确实是一个不错的选择。

Socket.IO Java 使用 Jetty Continuation API 来挂起和重新开始使用请求。它使用本机 Jetty WebSockets API 来支持 WebSocket。您可以使用 Socket.IO Java 确定哪一个服务器将与 Web 应用程序协同工作。

下面的 清单 5 显示了一个如何在服务器上使用 Socket.IO 的示例。您必须定义一个扩展 SocketIOServlet 的 servlet ,并实现返回某种端点表示形式的方法。此 API 与 WebSocket API 非常相似。该 API 的优势在于它可在服务器端使用,独立于客户端所选择的传输方式。Socket.IO 将所有的传输类型转化为与服务器端的 API 相同。

清单 5. 聊天示例 servlet 中使用的 Socket.IO Java 库
public final class ChatServlet extends SocketIOServlet { 
    private final BlockingQueue<Endpoint> endpoints = 
        new LinkedBlockingQueue<Endpoint>(); 
 
    @Override 
    protected SocketIOInbound doSocketIOConnect
                                        (HttpServletRequest request) { 
        String user = 
                (String) request.getSession().getAttribute("user"); 
        return user == null ? null : new Endpoint(this, user, request); 
    } 
 
    void broadcast(String data) { 
        for (Endpoint endpoint : endpoints) { 
            endpoint.send(data); 
        } 
    } 
 
    void add(Endpoint endpoint) { 
        endpoints.offer(endpoint); 
    } 
 
    void remove(Endpoint endpoint) { 
        endpoints.remove(endpoint); 
    } 
}

清单 6 显示了如何返回端点。

清单 6. 在聊天示例 Endpoint 中使用的 Socket.IO Java 库
class Endpoint implements SocketIOInbound { 
 
    [...]
 
    private SocketIOOutbound outbound; 
 
    [...]

    @Override 
    public void onConnect(SocketIOOutbound outbound) { 
        this.outbound = outbound; 
        servlet.add(this); 
        servlet.broadcast(user + " connected"); 
    } 
 
    @Override 
    public void onDisconnect(DisconnectReason reason, 
                             String errorMessage) { 
        outbound = null; 
        request.getSession().removeAttribute("user"); 
        servlet.remove(this); 
        servlet.broadcast(user + " disconnected"); 
    } 
 
    @Override 
    public void onMessage(int messageType, String message) { 
        if ("/disconnect".equals(message)) { 
            outbound.close(); 
        } else { 
            servlet.broadcast("[" + user + "] " + message); 
        } 
    } 
 
    void send(String data) { 
        try { 
            if (outbound != null 
    && outbound.getConnectionState() == ConnectionState.CONNECTED) { 
                outbound.sendMessage(data); 
            } 
        } catch (IOException e) { 
            outbound.close(); 
        } 
    } 
 
}
分享到:
评论

相关推荐

    LiveChat:使用Webpack,Socket.io,React,Express,MongoDB和Node.js构建的实时聊天室

    :person_running: 使用Socket.io,React,MongoDB,Express和Node.js构建的实时聊天室 前端框架: React,React-dom 前端Ajax通信: axios,socket.io-client 前端Web RWD设计: Material-ui,livechat-ui 后端...

    node.js中的socket.io入门实例

    5. 创建Client端应用:在Web页面中引入`socket.io.min.js`,并使用JavaScript创建Socket.IO连接,如示例中的`index.php`,通过`io.connect()`方法连接到服务器,并监听和发送事件。 在示例中,服务器端`test.js`...

    java-web聊天室源码

    - **AJAX**:异步JavaScript和XML,用于实现页面不刷新的情况下与服务器交互,提高用户体验。 - **Web Storage**:HTML5的本地存储机制,用于替代传统的Cookie,提供更大的存储空间,可以用于存储用户聊天记录。 ...

    毕业设计:前后端分离的即时通讯系统.zip

    - **Socket.IO**:一个库,提供了WebSocket的跨平台兼容性和附加功能,如心跳检测和重连机制。 5. **身份验证和授权**: - **OAuth2.0/JWT(JSON Web Tokens)**:用于用户登录认证,确保安全的数据传输和访问...

    我爱聊天web

    - **Socket.IO**:实现实时双向通信的关键技术,使得前端和后端可以即时交换消息,实现聊天功能。 3. **数据库**: - **MongoDB/MySQL/PostgreSQL**:项目可能使用其中任何一种数据库系统来存储用户信息、聊天...

    JavaScript MySQL实现在线打车系统【优质毕业设计、课程设计项目】.zip

    - 使用Nginx或者Apache等Web服务器进行反向代理和负载均衡。 这个项目不仅提供了学习JavaScript和MySQL的机会,还能让学生掌握前后端交互、数据库设计以及项目部署的实际操作,是提升综合技能的好材料。通过分析和...

    Node.js-shared-editor基于Nodejs的在线共享编辑器。

    1. **WebSocket**:提供全双工通信,一旦建立连接,客户端和服务器可以随时发送数据,适合实时应用。 2. **Socket.IO**:在WebSocket不兼容的情况下,Socket.IO能提供跨平台、跨协议的实时通信解决方案,它会自动...

    chat_adduono_com:chat.adduono.com的源代码,这是我年轻时尚未完成的项目-Chat source code

    - **JSON Web Tokens (JWT)**: 一种安全的身份验证机制,用于在客户端和服务器之间传输信息。 - **Passport.js**: Node.js的认证库,支持多种身份验证策略,如OAuth、JWT等。 5. **部署与服务器管理**: - **...

    网络聊天室

    服务器端通常会设计一套消息协议,如自定义的文本协议、JSON-RPC或WebSocket,用于客户端和服务器之间的数据交互。 前端部分,HTML、CSS和JavaScript是构建用户界面的基础。随着Web技术的发展,现代的聊天室往往...

    java技术规划.docx

    - **Nginx**:反向代理和负载均衡,提升Web服务性能。 - **CRM项目实战**:利用所学技术进行实际项目开发,巩固理论知识。 通过以上各个阶段的学习和实践,Java开发者能够逐步掌握从基础到高级的Java技术,具备...

    ChatRoom:Node.js 的 ChatRoom 应用程序——自学

    4. **Socket.IO**:为了跨浏览器兼容和提供实时通信,开发者可能选择了 Socket.IO。它在 WebSocket 之上提供了一层抽象,能自动处理各种浏览器的兼容性问题,同时提供了多种备用通信方式(如 AJAX 长轮询),确保...

    一流聊天天室

    WebSocket API需要与服务器端的Socket服务配合,常见的服务器端框架有Node.js的socket.io库,它可以轻松处理WebSocket连接和数据传输。 其次,【留言】功能则依赖于后端数据库存储。开发者可能采用了MySQL、SQLite...

    java北京地区简历_java简历.doc

    5. **IO流**:Java的IO流用于处理输入和输出,字节流处理二进制数据,字符流处理文本数据,了解它们的区别和转换是进行文件操作的基础。 6. **TCP/IP网络编程**:TCP/IP协议族是互联网的基础,Java的Socket编程可以...

    2017年尚学堂Java培训课程大纲.docx

    #### 第二阶段:Web技术和Java EE核心技术 ##### 2.1 Web基础 - **HTML、CSS、JavaScript**:熟悉网页的基本组成元素,掌握HTML标记语言、CSS样式表和JavaScript脚本语言的基本用法。 - **HTTP协议和Web服务器**:...

    chat-app

    3. **Socket.IO**:为了实现即时通讯,项目可能采用了Socket.IO库。它允许创建实时、双向的通信信道,确保消息在客户端和服务器之间实时同步。通过WebSocket协议,Socket.IO能处理各种网络条件下的连接问题,确保...

    JavaEE求职简历-姓名-JAVA开发工程师-范文.doc

    1. **JAVA基础**:深入理解面向对象编程,熟悉多线程、IO流、网络编程(UDP/TCP、socket),擅长文件操作(上传下载)、XML和JSON解析,能够运用servlet、filter、listener,同时对HTTP协议有深刻理解。 2. **...

    java学习历程

    Nginx是一个高性能的HTTP和反向代理服务器,它可以用来负载均衡和缓存静态资源,从而提高Web服务的整体性能。 通过以上四个阶段的学习,不仅可以掌握Java的基础知识,还能深入了解前端技术、主流框架的应用以及实际...

    unstableChat:这个想法是创建一个网络聊天,该网络聊天不会保存任何消息,基本上是人们可以交谈的临时聊天,然后我将其丢弃

    这可能涉及Nginx、Apache等反向代理服务器,或者使用云服务提供的负载均衡解决方案。同时,要优化PHP代码以减少计算资源的消耗。 7. **实时性与用户体验**:良好的用户体验是聊天应用的关键,包括消息的即时显示、...

    flask-socketio实现WebSocket的方法

    不过,反向ajax的代价也很明显,只要客户端还和服务端要有信息交互,服务端就必须还维持客户端的这个请求,然后在合适的时候返回。当客户端一多,这么做的成本会比较大。 其他的后端推前端的技术还有类似于隐藏...

Global site tag (gtag.js) - Google Analytics