WebSocket 是一种通信协议,它在单个 TCP 连接上提供全双工通信通道。以下是有关 WebSocket 的一些关键点:
-
全双工通信:与 HTTP 不同,HTTP 是一种请求-响应协议,而 WebSocket 允许客户端和服务器之间的双向通信。双方可以同时发送和接收数据。
-
连接生命周期:
- 握手:WebSocket 连接以 HTTP 握手开始,客户端请求升级到 WebSocket 协议。如果服务器同意,则建立连接。
- 打开:一旦连接建立,它将保持打开状态,允许持续通信。
- 消息:双方可以随时以消息的形式发送数据。
- 关闭:客户端或服务器都可以关闭连接。
-
低延迟:与 HTTP 轮询或长轮询相比,WebSocket 连接设计为低延迟且更高效,适用于实时通信。
-
应用场景:WebSocket 广泛应用于需要实时更新的应用程序,如在线聊天应用、网络游戏、实时金融数据推送和协同编辑。
-
API:WebSocket 得到了大多数现代浏览器的支持,可以使用简单的 JavaScript API 在客户端上使用。在服务器端,不同编程语言中有各种库和框架支持 WebSocket。
以下是如何使用 WebSocket 的简单示例:
当然,这里是使用 C 语言实现 WebSocket 客户端和服务器的示例。为了简化示例,假设使用 libwebsockets
库。你可以从 libwebsockets 网站获取更多信息,并安装该库。
客户端(C 语言)
#include <libwebsockets.h>
#include <string.h>static int callback(struct lws *wsi, enum lws_callback_reasons reason,void *user, void *in, size_t len) {switch (reason) {case LWS_CALLBACK_CLIENT_ESTABLISHED:lwsl_user("Connection established\n");lws_callback_on_writable(wsi);break;case LWS_CALLBACK_CLIENT_RECEIVE:lwsl_user("Received: %s\n", (char *)in);break;case LWS_CALLBACK_CLIENT_WRITEABLE:{char *msg = "Hello Server!";unsigned char buf[LWS_PRE + strlen(msg)];memcpy(&buf[LWS_PRE], msg, strlen(msg));lws_write(wsi, &buf[LWS_PRE], strlen(msg), LWS_WRITE_TEXT);}break;case LWS_CALLBACK_CLIENT_CLOSED:lwsl_user("Connection closed\n");break;default:break;}return 0;
}static struct lws_protocols protocols[] = {{ "example-protocol", callback, 0, 1024 },{ NULL, NULL, 0, 0 }
};int main(void) {struct lws_context_creation_info info;memset(&info, 0, sizeof(info));info.port = CONTEXT_PORT_NO_LISTEN;info.protocols = protocols;struct lws_context *context = lws_create_context(&info);if (!context) {lwsl_err("lws_create_context failed\n");return 1;}struct lws_client_connect_info ccinfo = {0};ccinfo.context = context;ccinfo.address = "localhost";ccinfo.port = 8080;ccinfo.path = "/";ccinfo.host = lws_canonical_hostname(context);ccinfo.origin = "origin";ccinfo.protocol = protocols[0].name;struct lws *wsi = lws_client_connect_via_info(&ccinfo);if (!wsi) {lwsl_err("lws_client_connect_via_info failed\n");return 1;}while (lws_service(context, 1000) >= 0);lws_context_destroy(context);return 0;
}
服务器(C 语言)
#include <libwebsockets.h>
#include <string.h>static int callback(struct lws *wsi, enum lws_callback_reasons reason,void *user, void *in, size_t len) {switch (reason) {case LWS_CALLBACK_ESTABLISHED:lwsl_user("Connection established\n");break;case LWS_CALLBACK_RECEIVE:lwsl_user("Received: %s\n", (char *)in);{char *msg = "Hello Client!";unsigned char buf[LWS_PRE + strlen(msg)];memcpy(&buf[LWS_PRE], msg, strlen(msg));lws_write(wsi, &buf[LWS_PRE], strlen(msg), LWS_WRITE_TEXT);}break;case LWS_CALLBACK_CLOSED:lwsl_user("Connection closed\n");break;default:break;}return 0;
}static struct lws_protocols protocols[] = {{ "example-protocol", callback, 0, 1024 },{ NULL, NULL, 0, 0 }
};int main(void) {struct lws_context_creation_info info;memset(&info, 0, sizeof(info));info.port = 8080;info.protocols = protocols;struct lws_context *context = lws_create_context(&info);if (!context) {lwsl_err("lws_create_context failed\n");return 1;}while (lws_service(context, 1000) >= 0);lws_context_destroy(context);return 0;
}
在这两个示例中,我们分别创建了一个 WebSocket 客户端和服务器,并通过 libwebsockets
库进行
当然,这里是使用 Java 实现 WebSocket 客户端和服务器的示例。我们将使用 Java 的标准库 javax.websocket
来实现。
客户端(Java)
首先,确保你有 javax.websocket
库。它包含在 Java EE 或者可以通过 Maven 获取:
<dependency><groupId>javax.websocket</groupId><artifactId>javax.websocket-api</artifactId><version>1.1</version>
</dependency>
以下是 WebSocket 客户端的示例:
import javax.websocket.ClientEndpoint;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.ContainerProvider;
import javax.websocket.WebSocketContainer;
import java.net.URI;@ClientEndpoint
public class WebSocketClient {@OnOpenpublic void onOpen(Session session) {System.out.println("Connected to server");try {session.getBasicRemote().sendText("Hello Server!");} catch (Exception e) {e.printStackTrace();}}@OnMessagepublic void onMessage(String message) {System.out.println("Received message: " + message);}public static void main(String[] args) {WebSocketContainer container = ContainerProvider.getWebSocketContainer();String uri = "ws://localhost:8080/websocket";System.out.println("Connecting to " + uri);try {container.connectToServer(WebSocketClient.class, URI.create(uri));} catch (Exception e) {e.printStackTrace();}}
}
服务器(Java)
服务器端我们使用 javax.websocket
和一个嵌入式的 Jetty 服务器。首先,添加 Maven 依赖项:
<dependency><groupId>javax.websocket</groupId><artifactId>javax.websocket-server-api</artifactId><version>1.1</version>
</dependency>
<dependency><groupId>org.eclipse.jetty</groupId><artifactId>jetty-server</artifactId><version>9.4.35.v20201120</version>
</dependency>
<dependency><groupId>org.eclipse.jetty</groupId><artifactId>jetty-webapp</artifactId><version>9.4.35.v20201120</version>
</dependency>
<dependency><groupId>org.eclipse.jetty.websocket</groupId><artifactId>websocket-server</artifactId><version>9.4.35.v20201120</version>
</dependency>
<dependency><groupId>org.eclipse.jetty.websocket</groupId><artifactId>javax-websocket-server-impl</artifactId><version>9.4.35.v20201120</version>
</dependency>
以下是 WebSocket 服务器的示例:
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;@ServerEndpoint("/websocket")
public class WebSocketServer {@OnOpenpublic void onOpen(Session session) {System.out.println("Client connected");}@OnMessagepublic void onMessage(String message, Session session) {System.out.println("Received message: " + message);try {session.getBasicRemote().sendText("Hello Client!");} catch (Exception e) {e.printStackTrace();}}@OnClosepublic void onClose(Session session) {System.out.println("Connection closed");}public static void main(String[] args) throws Exception {Server server = new Server(8080);ContextHandler context = new ContextHandler();context.setContextPath("/");server.setHandler(context);WebSocketServerContainerInitializer.configureContext(context);context.addServlet(WebSocketServer.class, "/websocket");server.start();server.join();}
}
在这个示例中,我们创建了一个简单的 WebSocket 服务器,并使用嵌入式 Jetty 服务器运行。客户端连接到服务器后,发送 “Hello Server!” 消息,服务器接收到消息后回复 “Hello Client!”。
要运行这些示例,请确保添加了相应的依赖项,并根据需要调整你的项目设置。