WebSocket

WebSocket 是一种通信协议,它在单个 TCP 连接上提供全双工通信通道。以下是有关 WebSocket 的一些关键点:

  1. 全双工通信:与 HTTP 不同,HTTP 是一种请求-响应协议,而 WebSocket 允许客户端和服务器之间的双向通信。双方可以同时发送和接收数据。

  2. 连接生命周期

    • 握手:WebSocket 连接以 HTTP 握手开始,客户端请求升级到 WebSocket 协议。如果服务器同意,则建立连接。
    • 打开:一旦连接建立,它将保持打开状态,允许持续通信。
    • 消息:双方可以随时以消息的形式发送数据。
    • 关闭:客户端或服务器都可以关闭连接。
  3. 低延迟:与 HTTP 轮询或长轮询相比,WebSocket 连接设计为低延迟且更高效,适用于实时通信。

  4. 应用场景:WebSocket 广泛应用于需要实时更新的应用程序,如在线聊天应用、网络游戏、实时金融数据推送和协同编辑。

  5. API:WebSocket 得到了大多数现代浏览器的支持,可以使用简单的 JavaScript API 在客户端上使用。在服务器端,不同编程语言中有各种库和框架支持 WebSocket。

以下是如何使用 WebSocket 的简单示例:

当然,这里是使用 C 语言实现 WebSocket 客户端和服务器的示例。为了简化示例,假设使用 libwebsockets 库。你可以从 libwebsockets 网站获取更多信息,并安装该库。

客户端(C 语言)

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 语言)

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 获取:

xml 复制代码
<dependency>
    <groupId>javax.websocket</groupId>
    <artifactId>javax.websocket-api</artifactId>
    <version>1.1</version>
</dependency>

以下是 WebSocket 客户端的示例:

java 复制代码
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 {
    @OnOpen
    public void onOpen(Session session) {
        System.out.println("Connected to server");
        try {
            session.getBasicRemote().sendText("Hello Server!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @OnMessage
    public 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 依赖项:

xml 复制代码
<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 服务器的示例:

java 复制代码
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 {
    @OnOpen
    public void onOpen(Session session) {
        System.out.println("Client connected");
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("Received message: " + message);
        try {
            session.getBasicRemote().sendText("Hello Client!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @OnClose
    public 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!"。

要运行这些示例,请确保添加了相应的依赖项,并根据需要调整你的项目设置。

相关推荐
shykevin4 小时前
python开发Streamable HTTP MCP应用
开发语言·网络·python·网络协议·http
tmacfrank5 小时前
网络编程中的直接内存与零拷贝
java·linux·网络
数据与人工智能律师7 小时前
虚拟主播肖像权保护,数字时代的法律博弈
大数据·网络·人工智能·算法·区块链
purrrew8 小时前
【Java ee初阶】HTTP(2)
网络·网络协议·http
火星数据-Tina8 小时前
从HTTP轮询到WebSocket:如何让体育API性能提升100倍?
websocket·网络协议·http
hgdlip10 小时前
怎么快速换电脑浏览器的ip:方法与注意事项
网络·网络协议·tcp/ip·电脑
可怜的Tom被玩弄于股掌之中10 小时前
BUUCTF——Nmap
网络·安全·web安全·网络安全
今儿敲了吗12 小时前
计网| 网际控制报文协议(ICMP)
网络·智能路由器
南棱笑笑生13 小时前
20250515测试飞凌的OK3588-C的核心板在Linux R4下适配以太网RTL8211F-CG时跑iperf3的极速
linux·服务器·网络
Think Spatial 空间思维13 小时前
【HTTPS基础概念与原理】TLS握手过程详解
数据库·网络协议·https