ZeroMQ:事件监控

#include <stdio.h>
#include <zmq.h>
#include <string.h>
#include <assert.h>
#include <malloc.h>

//http://api.zeromq.org/4-2:zmq-socket-monitor

static int get_monitor_event(void* monitor, int* value, char* address)
{
	// First frame in message contains event number and value
	zmq_msg_t msg;
	zmq_msg_init(&msg);
	if (zmq_msg_recv(&msg, monitor, 0) == -1)
		return -1; // Interrupted, presumably
	assert(zmq_msg_more(&msg));

	uint8_t* data = (uint8_t*)zmq_msg_data(&msg);
	uint16_t event = *(uint16_t*)(data);
	if (value)
		*value = *(uint32_t*)(data + 2);

	zmq_msg_close(&msg);
	// Second frame in message contains event address
	zmq_msg_init(&msg);
	if (zmq_msg_recv(&msg, monitor, 0) == -1)
		return -1; // Interrupted, presumably
	assert(!zmq_msg_more(&msg));

	if (address) {
		uint8_t* data = (uint8_t*)zmq_msg_data(&msg);
		size_t size = zmq_msg_size(&msg);

		memcpy(address, data, size);
		address[size] = 0;
	}

	zmq_msg_close(&msg);
	return event;
}

typedef struct
{
	int event;
	char* desc;
}ZMQ_EVENT_TABLE;

#define ZMQ_EVENT_DEF(event)\
	{event, #event}

/*
static ZMQ_EVENT_TABLE zmq_event_table[] = {
	//{ZMQ_EVENT_CONNECTED,		"ZMQ_EVENT_CONNECTED"},
	ZMQ_EVENT_DEF(ZMQ_EVENT_CONNECTED),
	{ZMQ_EVENT_CONNECT_DELAYED, "ZMQ_EVENT_CONNECT_DELAYED"},
	{ZMQ_EVENT_CONNECT_RETRIED, "ZMQ_EVENT_CONNECT_RETRIED"},
	{ZMQ_EVENT_LISTENING,		"ZMQ_EVENT_LISTENING"},
	{ZMQ_EVENT_BIND_FAILED,		"ZMQ_EVENT_BIND_FAILED"},
	{ZMQ_EVENT_ACCEPTED,		"ZMQ_EVENT_ACCEPTED"},
	{ZMQ_EVENT_ACCEPT_FAILED,	"ZMQ_EVENT_ACCEPT_FAILED"},
	{ZMQ_EVENT_CLOSED,			"ZMQ_EVENT_CLOSED"},
	{ZMQ_EVENT_CLOSE_FAILED,	"ZMQ_EVENT_CLOSE_FAILED"},
	{ZMQ_EVENT_DISCONNECTED,	"ZMQ_EVENT_DISCONNECTED"},
	{ZMQ_EVENT_MONITOR_STOPPED, "ZMQ_EVENT_MONITOR_STOPPED"},
	{ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL, "ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL"},
	{ZMQ_EVENT_HANDSHAKE_SUCCEEDED, "ZMQ_EVENT_HANDSHAKE_SUCCEEDED"},
	{ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL, "ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL"},
	{ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, "ZMQ_EVENT_HANDSHAKE_FAILED_AUTH"}
};
*/
static ZMQ_EVENT_TABLE zmq_event_table[] = {
	ZMQ_EVENT_DEF(ZMQ_EVENT_CONNECTED),
	ZMQ_EVENT_DEF(ZMQ_EVENT_CONNECT_DELAYED),
	ZMQ_EVENT_DEF(ZMQ_EVENT_CONNECT_RETRIED),
	ZMQ_EVENT_DEF(ZMQ_EVENT_LISTENING),
	ZMQ_EVENT_DEF(ZMQ_EVENT_BIND_FAILED),
	ZMQ_EVENT_DEF(ZMQ_EVENT_ACCEPTED),
	ZMQ_EVENT_DEF(ZMQ_EVENT_ACCEPT_FAILED),
	ZMQ_EVENT_DEF(ZMQ_EVENT_CLOSED),
	ZMQ_EVENT_DEF(ZMQ_EVENT_CLOSE_FAILED),
	ZMQ_EVENT_DEF(ZMQ_EVENT_DISCONNECTED),
	ZMQ_EVENT_DEF(ZMQ_EVENT_MONITOR_STOPPED),
	ZMQ_EVENT_DEF(ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL),
	ZMQ_EVENT_DEF(ZMQ_EVENT_HANDSHAKE_SUCCEEDED),
	ZMQ_EVENT_DEF(ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL),
	ZMQ_EVENT_DEF(ZMQ_EVENT_HANDSHAKE_FAILED_AUTH)
};


char* zmq_strevent(int event)
{
	int idx;

	for (idx = 0; idx < sizeof(zmq_event_table) / sizeof(ZMQ_EVENT_TABLE); idx++) {
		if (event & zmq_event_table[idx].event) {
			return zmq_event_table[idx].desc;
		}
	}

	return "unknown event";
}

static void rep_socket_monitor(void* ctx)
{
	int value;
	char addr[2048];
	int rc;

	printf("starting monitor...\n");
	void* s = zmq_socket(ctx, ZMQ_PAIR);
	assert(s);
	rc = zmq_connect(s, "inproc://monitor.rep");
	assert(rc == 0);
	rc = 1;
	while (rc != -1) {
		rc = get_monitor_event(s, &value, addr);
		if (rc != -1) {
			printf("event : %d,%s, value %d @ addr %s\r\n", rc, zmq_strevent(rc), value, addr);
			continue;
		}
		printf("errno : %s\r\n", zmq_strerror(errno));
	}
	zmq_close(s);
}

void dump_msg(const void* data, int size)
{
	unsigned char* ptr = (unsigned char*)data;
	printf("[%03d] ", size);
	int i = 0;
	for (i = 0; i < size; i++)
		printf("%02X", ptr[i]);
	printf("\n");
}

static void wait_thread(void* socket)
{
	int more;

	while (1) {
		zmq_msg_t msg;
		zmq_msg_init(&msg);
		
		if (zmq_msg_recv(&msg, socket, 0) == -1)
			return;
		more = zmq_msg_more(&msg);

		uint8_t* data = (uint8_t*)zmq_msg_data(&msg);
		size_t size = zmq_msg_size(&msg);

		dump_msg(data, size);

		zmq_msg_send(&msg, socket, 0);
		zmq_sleep(1);
	}
}

int main()
{
	const char* addr = "tcp://127.0.0.1:6666";

	void* ctx = zmq_init(1);
	assert(ctx);

	void* rep = zmq_socket(ctx, ZMQ_REP);
	assert(rep);

	int rc = zmq_socket_monitor(rep, "inproc://monitor.rep", ZMQ_EVENT_ALL);
	assert(rc == 0);

	zmq_threadstart(rep_socket_monitor, ctx);
	assert(rc == 0);
	rc = zmq_bind(rep, addr);
	assert(rc == 0);

	// Allow some time for event detection
	//zmq_sleep(1);
	wait_thread(rep);

	rc = zmq_close(rep);
	assert(rc == 0);
	zmq_term(ctx);
	return 0;
}
starting monitor...
event : 8,ZMQ_EVENT_LISTENING, value 420 @ addr tcp://127.0.0.1:6666
event : 32,ZMQ_EVENT_ACCEPTED, value 424 @ addr tcp://127.0.0.1:6666
event : 4096,ZMQ_EVENT_HANDSHAKE_SUCCEEDED, value 0 @ addr tcp://127.0.0.1:6666
event : 512,ZMQ_EVENT_DISCONNECTED, value 424 @ addr tcp://127.0.0.1:6666
event : 32,ZMQ_EVENT_ACCEPTED, value 436 @ addr tcp://127.0.0.1:6666
event : 4096,ZMQ_EVENT_HANDSHAKE_SUCCEEDED, value 0 @ addr tcp://127.0.0.1:6666
[001] 61
[005] 6262626262
[007] 73616466617366
[031] 61736661736666666666666666666666666666666666666666666666666666
[026] 6161616161616161616161616161616161616161616161616161
[004] 6D6D6D6D
[010] 61736466617366617366
[005] 6166617364
[010] 69206C6F766520796F75
event : 512,ZMQ_EVENT_DISCONNECTED, value 436 @ addr tcp://127.0.0.1:6666
event : 32,ZMQ_EVENT_ACCEPTED, value 436 @ addr tcp://127.0.0.1:6666
event : 4096,ZMQ_EVENT_HANDSHAKE_SUCCEEDED, value 0 @ addr tcp://127.0.0.1:6666
[006] 313233343536
[008] 6661736466617366
[011] 6173666173646661736664
[010] 67617366617366646173
[008] 6173646661736661
[009] 617364666173666173
[009] 616661647364666173
import zmq, sys

context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect("tcp://localhost:6666")
while True:
    data = input("input your data:")
    if data == 'q':
        sys.exit()
    socket.send_string(data)
    response = socket.recv_string()
    print("recv : ", response)
D:\source\python\pikatest\Scripts\python.exe C:/Users/Administrator/PycharmProjects/pythonProject/zmq-1/zmq_client1.py
input your data:123456
recv :  123456
input your data:fasdfasf
recv :  fasdfasf
input your data:asfasdfasfd
recv :  asfasdfasfd
input your data:gasfasfdas
recv :  gasfasfdas
input your data:asdfasfa
recv :  asdfasfa
input your data:asdfasfas
recv :  asdfasfas
input your data:afadsdfas
recv :  afadsdfas

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ZeroMQ是一种在云时代中提供极速消息通信的库。ZeroMQ是一个开源的、高性能的消息传递库,它能够以非常低的延迟和高吞吐量进行快速的消息传输。 ZeroMQ的设计理念是简单易用,同时具备灵活性和可扩展性。它提供了简单而灵活的API,允许开发人员使用不同的通信模式和拓扑结构来构建自己的通信系统。 ZeroMQ的架构基于Socket通信模型,它提供了各种编程语言的绑定,包括C、C++、Python、Java等。这意味着开发人员可以使用自己熟悉的编程语言来开发使用ZeroMQ的应用程序。 ZeroMQ支持多种消息传输模式,包括点对点通信、发布-订阅模式、请求-回应模式和路由模式。开发人员可以根据具体的需求选择最合适的模式来进行消息通信。 ZeroMQ的特点之一是其高性能。它通过使用高效的消息队列机制,最大限度地减少了消息传输的延迟。同时,ZeroMQ还支持并发处理和多线程操作,可以在多核系统中充分利用计算资源,提高系统的吞吐量和性能。 另一个重要的特点是ZeroMQ的可扩展性。它的架构允许开发人员构建分布式系统,并通过添加更多的节点来扩展系统的规模和容量。ZeroMQ还提供了一套高级的路由和负载均衡机制,使得开发人员可以轻松地构建高可用性和高可伸缩性的系统。 综上所述,ZeroMQ是一个在云时代中非常有用的极速消息通信库。它简单易用、性能高效、可扩展性强,可以满足各种复杂的消息通信需求。无论是构建实时数据处理系统、构建高并发的网络服务,还是构建分布式应用程序,ZeroMQ都是一个值得考虑的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值