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!"。

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

相关推荐
不爱学习的YY酱1 小时前
【计网不挂科】计算机网络期末考试——【选择题&填空题&判断题&简述题】试卷(4)
网络·计算机网络
装睡的小5郎1 小时前
家庭宽带如何开启公网ipv4和ipv6
网络
yfs10241 小时前
压缩Minio桶中的文件为ZIP,并通过 HTTP 响应输出
网络·网络协议·http
有谁看见我的剑了?1 小时前
Ubuntu 22.04.5 配置vlan子接口和网桥
服务器·网络·ubuntu
hgdlip1 小时前
有什么办法换网络ip动态
网络·tcp/ip·智能路由器
超栈1 小时前
HCIP(11)-期中综合实验(BGP、Peer、OSPF、VLAN、IP、Route-Policy)
运维·网络·网络协议·计算机网络·web安全·网络安全·信息与通信
დ旧言~1 小时前
【网络】应用层——HTTP协议
开发语言·网络·网络协议·http·php
不爱学习的YY酱1 小时前
【计网不挂科】计算机网络期末考试——【选择题&填空题&判断题&简述题】试卷(1)
网络·计算机网络
汪小敏同学1 小时前
【Django进阶】django-rest-framework中文文档——快速入门
网络·windows·oracle
徐浪老师1 小时前
OSPF动态路由配置实验:实现高效网络自动化
网络·自动化·智能路由器