Skip to content

Commit bd86026

Browse files
committed
add Sec-WebSocket-Protocol
add example Signed-off-by: Gabriele Santomaggio <G.santomaggio@gmail.com>
1 parent 49f214f commit bd86026

4 files changed

Lines changed: 104 additions & 1 deletion

File tree

docs/examples/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111
- [Advanced Settings](advanced_settings) - An example of how to use the advanced connection settings of the AMQP 1.0 client.
1212
- [Broadcast](broadcast) - An example of how to use fanout to broadcast messages to multiple auto-deleted queues.
1313
- [RPC Echo](rpc_echo_server) - An example of how to implement RPC with the AMQP 1.0 client.
14-
- [SQL stream Filtering](sql_stream_filter) - An example of how to use SQL stream filtering with RabbitMQ Streams.
14+
- [SQL stream Filtering](sql_stream_filter) - An example of how to use SQL stream filtering with RabbitMQ Streams.
15+
- [Web Sockets](web_sockets) - An example of how to use Web Sockets with the AMQP 1.0 client.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
AMQP 1.0 over WebSocket Example
2+
===============================================================
3+
4+
This example demonstrates how to use AMQP 1.0 over WebSocket. </br>
5+
## RabbitMQ Tanzu
6+
You need [Tanzu RabbitMQ 4.0](https://www.vmware.com/products/app-platform/tanzu-rabbitmq) or later with the AMQP 1.0 and `rabbitmq_web_amqp` plugins enabled.
7+
8+
For more info read the blog post: [AMQP 1.0 over WebSocket](https://www.rabbitmq.com/blog/2025/04/16/amqp-websocket)
9+
10+
To run the example you need to have:
11+
- Tanzu RabbitMQ 4.0 or later with the AMQP 1.0 and `rabbitmq_web_amqp` plugins enabled.
12+
- A vhost called `ws` configured for WebSocket connections.
13+
- A user `rabbit` pwd `rabbit` with access to the `ws` vhost.
14+
15+
## Web Sockify
16+
It is possible to run the example with [websockify](https://github.com/novnc/websockify)
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// RabbitMQ AMQP 1.0 Go Client: https://github.com/rabbitmq/rabbitmq-amqp-go-client
2+
// RabbitMQ AMQP 1.0 documentation: https://www.rabbitmq.com/docs/amqp
3+
// The example is demonstrating how to connect to RabbitMQ using AMQP 1.0 over WebSocket protocol,
4+
// declare a queue, publish a message to it, and then consume that message.
5+
// AMQP 1.0 over WebSocket documentation: https://www.rabbitmq.com/blog/2025/04/16/amqp-websocket
6+
// example path: https://github.com/rabbitmq/rabbitmq-amqp-go-client/tree/main/docs/examples//web_sockets/web_sockets.go
7+
8+
package main
9+
10+
import (
11+
"context"
12+
13+
rmq "github.com/rabbitmq/rabbitmq-amqp-go-client/pkg/rabbitmqamqp"
14+
)
15+
16+
func main() {
17+
const amqpConnectionString = "ws://rabbit:rabbit@127.0.0.1:15678/ws"
18+
rmq.Info("[Example]", "Starting web socket connection to", amqpConnectionString)
19+
env := rmq.NewEnvironment(amqpConnectionString, nil)
20+
conn, err := env.NewConnection(context.Background())
21+
if err != nil {
22+
panic(err)
23+
}
24+
_, err = conn.Management().DeclareQueue(context.TODO(), &rmq.QuorumQueueSpecification{
25+
Name: "test-ws-queue",
26+
})
27+
if err != nil {
28+
panic(err)
29+
}
30+
// declare new producer
31+
producer, err := conn.NewPublisher(context.TODO(), &rmq.QueueAddress{
32+
Queue: "test-ws-queue",
33+
}, nil)
34+
if err != nil {
35+
panic(err)
36+
}
37+
msg := rmq.NewMessage([]byte("Hello over WebSockets"))
38+
39+
publishResult, err := producer.Publish(context.Background(), msg)
40+
if err != nil {
41+
panic(err)
42+
}
43+
switch publishResult.Outcome.(type) {
44+
case *rmq.StateAccepted:
45+
rmq.Info("[Publisher]", "Message accepted", publishResult.Message.Data[0])
46+
default:
47+
rmq.Warn("[Publisher]", "Message not accepted", publishResult.Message.Data[0])
48+
}
49+
50+
// declare new consumer
51+
consumer, err := conn.NewConsumer(context.TODO(), "test-ws-queue", nil)
52+
if err != nil {
53+
panic(err)
54+
}
55+
deliveryContext, err := consumer.Receive(context.Background())
56+
if err != nil {
57+
panic(err)
58+
}
59+
rmq.Info("[Consumer]", "Message received", string(deliveryContext.Message().GetData()))
60+
err = deliveryContext.Accept(context.Background())
61+
if err != nil {
62+
panic(err)
63+
}
64+
// clean up
65+
err = consumer.Close(context.TODO())
66+
if err != nil {
67+
panic(err)
68+
}
69+
err = producer.Close(context.TODO())
70+
if err != nil {
71+
panic(err)
72+
}
73+
74+
err = conn.Management().DeleteQueue(context.Background(), "test-ws-queue")
75+
if err != nil {
76+
panic(err)
77+
}
78+
79+
err = conn.Close(context.TODO())
80+
if err != nil {
81+
panic(err)
82+
}
83+
84+
}

pkg/rabbitmqamqp/amqp_connection.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,8 @@ func sanitizeWebSocketURL(rawURL string) (string, http.Header, error) {
761761
// Construct Basic Auth Header manually
762762
auth := base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
763763
headers.Add("Authorization", "Basic "+auth)
764+
// add sec-websocket-protocol amqp
765+
headers.Add("Sec-WebSocket-Protocol", "amqp")
764766

765767
u.User = nil
766768
}

0 commit comments

Comments
 (0)