You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C编写STOMP WebSocket客户端连接Spring Boot服务端?

C语言WebSocket客户端对接Spring Boot STOMP服务指南

一、C客户端对STOMP协议的支持

完全支持。STOMP是基于文本的应用层协议,只要C客户端能建立WebSocket连接,就可以通过构造/解析STOMP格式的报文实现与Spring Boot STOMP服务端的交互。可以选择现成的STOMP库简化开发,也可以手动拼接符合规范的STOMP帧。

二、起步实现方向

1. 选择WebSocket基础库

首先需要实现底层WebSocket连接,推荐以下轻量易用的C语言库:

  • libwebsockets:功能全面,支持标准WebSocket协议,提供完善的事件回调机制,适合构建稳定的客户端。
  • wsclient:轻量级WebSocket客户端库,API简洁,适合快速原型开发。
  • libcurl:需开启WebSocket编译选项,可复用HTTP连接逻辑,适合已有curl依赖的项目。

2. 集成STOMP协议支持

  • 使用现成STOMP库:如libstomp,可直接封装STOMP帧的构造、解析逻辑,与WebSocket库配合使用,专注业务逻辑即可。
  • 手动实现STOMP帧:STOMP帧格式简单,可自行拼接字符串完成。核心帧格式规则:
    • 帧命令(如CONNECT、SEND、SUBSCRIBE)开头
    • 帧头(键值对,每行一个)
    • 空行分隔帧头与消息体
    • 消息体
    • 以NULL字符(ASCII 0)结尾

3. 对接你的Spring Boot服务端的具体步骤

步骤1:建立WebSocket连接

连接地址为服务端配置的端点:ws://<服务端IP>:<端口>/gs-guide-websocket
通过所选WebSocket库完成握手,建立双向连接。

步骤2:发送STOMP连接帧

连接成功后,发送CONNECT帧完成STOMP会话初始化:

CONNECT
accept-version:1.2
host:localhost

^@

注:^@代表ASCII 0字符,必须作为帧的结束标记。

服务端会返回CONNECTED帧,确认STOMP会话建立。

步骤3:订阅广播主题

发送SUBSCRIBE帧,订阅服务端的/topic/greetings主题,接收响应消息:

SUBSCRIBE
id:sub-1
destination:/topic/greetings

^@

id为自定义的订阅唯一标识,可任意指定。

步骤4:发送业务消息

发送SEND帧,对应服务端@MessageMapping("/hello")接口:

SEND
destination:/app/hello

你的消息内容
^@

消息体即为服务端greeting方法接收的参数。

步骤5:处理服务端响应

服务端处理完成后,会通过/topic/greetings发送MESSAGE帧,格式示例:

MESSAGE
message-id:xxx
destination:/topic/greetings

Hello, 你的消息内容!
^@

解析该帧,提取消息体即可获取响应内容。

4. 代码示例(基于libwebsockets)

以下是核心框架代码,展示连接、发送STOMP帧、接收消息的逻辑:

#include <libwebsockets.h>
#include <stdio.h>
#include <string.h>

static int callback_stomp_client(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) {
    switch (reason) {
        case LWS_CALLBACK_CLIENT_ESTABLISHED: {
            // 发送STOMP连接帧
            const char connect_frame[] = "CONNECT\naccept-version:1.2\nhost:localhost\n\n\x00";
            lws_write(wsi, (unsigned char*)connect_frame, strlen(connect_frame), LWS_WRITE_TEXT);
            break;
        }
        case LWS_CALLBACK_CLIENT_RECEIVE: {
            // 打印收到的STOMP帧
            printf("Received from server:\n%.*s\n", (int)len, (char*)in);
            // 可在此处解析MESSAGE帧,提取消息体
            break;
        }
        case LWS_CALLBACK_CLIENT_WRITEABLE: {
            // 连接稳定后发送测试消息
            const char send_frame[] = "SEND\ndestination:/app/hello\n\nHello from C Client!\x00";
            lws_write(wsi, (unsigned char*)send_frame, strlen(send_frame), LWS_WRITE_TEXT);
            break;
        }
        default:
            break;
    }
    return 0;
}

int main() {
    struct lws_context_creation_info ctx_info = {0};
    struct lws_client_connect_info conn_info = {0};
    struct lws_context *ctx;

    // 初始化上下文
    ctx_info.port = CONTEXT_PORT_NO_LISTEN;
    ctx_info.protocols = (struct lws_protocols[]) {
        {
            "stomp-ws",
            callback_stomp_client,
            0,
            4096,
        },
        {NULL, NULL, 0, 0}
    };

    ctx = lws_create_context(&ctx_info);
    if (!ctx) {
        fprintf(stderr, "Failed to create lws context\n");
        return 1;
    }

    // 配置连接参数
    conn_info.context = ctx;
    conn_info.address = "localhost";
    conn_info.port = 8080; // 替换为你的服务端端口
    conn_info.path = "/gs-guide-websocket";
    conn_info.host = conn_info.address;
    conn_info.origin = conn_info.address;
    conn_info.protocol = "stomp-ws";

    lws_client_connect_via_info(&conn_info);

    // 事件循环
    while (lws_service(ctx, 50) >= 0);

    lws_context_destroy(ctx);
    return 0;
}

编译命令(需已安装libwebsockets):

gcc stomp_client.c -o stomp_client -lwebsockets

三、关键注意事项

  • 严格遵守STOMP帧格式:帧头与消息体之间必须有一个空行,帧末尾必须加NULL字符,否则服务端无法解析。
  • 处理重连逻辑:WebSocket连接断开后,需重新建立连接并重新发起STOMP会话(包括CONNECT、SUBSCRIBE操作)。
  • 字符编码一致性:确保客户端与服务端使用相同的字符编码(如UTF-8),避免中文乱码。

内容的提问来源于stack exchange,提问作者voidMainReturn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 16:34:51