├── .gitignore ├── README.md ├── examples ├── rabbitmq_pub.lua └── rabbitmq_sub.lua └── rabbitmqstomp.lua /.gitignore: -------------------------------------------------------------------------------- 1 | # 如果有需要,也可以加到仓库中 2 | .vscode 3 | .idea 4 | *.out 5 | *.pid 6 | *.o 7 | *.so 8 | *.lib 9 | *.tar.gz 10 | *.log 11 | *.svn 12 | .DS_Store* 13 | ._* 14 | .DS_Store 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # skynet_rabbitmq 2 | fork from https://github.com/wingify/lua-resty-rabbitmqstomp 3 | -------------------------------------------------------------------------------- /examples/rabbitmq_pub.lua: -------------------------------------------------------------------------------- 1 | -- https://www.howtoforge.com/tutorial/how-to-install-rabbitmq-server-on-centos-7/ 2 | -- https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.15/rabbitmq-server-3.6.15-1.el7.noarch.rpm 3 | -- rabbitmq-plugins enable rabbitmq_stomp 4 | --https://www.rabbitmq.com/stomp.html 5 | -- https://www.rabbitmq.com/management-cli.html 6 | -- https://www.rabbitmq.com/rabbitmqctl.8.html 7 | -- https://stackoverflow.com/questions/40436425/how-do-i-create-or-add-a-user-to-rabbitmq 8 | 9 | local skynet = require "skynet" 10 | local cjson = require "cjson" 11 | local rabbitmq = require "rabbitmq.rabbitmqstomp" 12 | 13 | return function() 14 | skynet.timeout( 15 | 10 * 100, 16 | function() 17 | local mq = 18 | rabbitmq.connect( 19 | {host = "127.0.0.1", port = 61613}, 20 | {username = "guest", password = "guest", vhost = "/"} 21 | ) 22 | 23 | local msg = {key = "value1", key2 = "value2"} 24 | local headers = {} 25 | headers["destination"] = "/exchange/test" 26 | headers["receipt"] = "msg#1" 27 | headers["app-id"] = "skynet_rabbitmq" 28 | headers["persistent"] = "true" 29 | headers["content-type"] = "application/json" 30 | 31 | local res = mq:send(cjson.encode(msg), headers) 32 | skynet.error("published:", res) 33 | 34 | mq:close() 35 | end 36 | ) 37 | end 38 | -------------------------------------------------------------------------------- /examples/rabbitmq_sub.lua: -------------------------------------------------------------------------------- 1 | -- https://www.howtoforge.com/tutorial/how-to-install-rabbitmq-server-on-centos-7/ 2 | -- https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.15/rabbitmq-server-3.6.15-1.el7.noarch.rpm 3 | -- rabbitmq-plugins enable rabbitmq_stomp 4 | --https://www.rabbitmq.com/stomp.html 5 | -- https://www.rabbitmq.com/management-cli.html 6 | -- https://www.rabbitmq.com/rabbitmqctl.8.html 7 | -- https://stackoverflow.com/questions/40436425/how-do-i-create-or-add-a-user-to-rabbitmq 8 | 9 | local skynet = require "skynet" 10 | local rabbitmq = require "rabbitmq.rabbitmqstomp" 11 | 12 | return function() 13 | local mq = 14 | rabbitmq.connect({host = "127.0.0.1", port = 61613}, {username = "guest", password = "guest", vhost = "/"}) 15 | 16 | do 17 | local headers = {} 18 | headers["destination"] = "/amq/queue/test" 19 | headers["persistent"] = "true" 20 | headers["id"] = "123" 21 | local res = 22 | mq:subscribe( 23 | headers, 24 | function(data) 25 | skynet.error("consumed:", data) 26 | mq:unsubscribe(headers) 27 | end 28 | ) 29 | skynet.error("subscribe:", res) 30 | end 31 | 32 | mq:receive() 33 | 34 | -- mq:close() 35 | end 36 | -------------------------------------------------------------------------------- /rabbitmqstomp.lua: -------------------------------------------------------------------------------- 1 | -- lua-resty-rabbitmqstomp: Opinionated RabbitMQ (STOMP) client lib 2 | -- Copyright (C) 2013 Rohit 'bhaisaab' Yadav, Wingify 3 | -- Opensourced at Wingify in New Delhi under the MIT License 4 | 5 | local concat = table.concat 6 | local find = string.find 7 | local insert = table.insert 8 | local len = string.len 9 | local pairs = pairs 10 | local setmetatable = setmetatable 11 | local sub = string.sub 12 | 13 | local skynet = require "skynet" 14 | local socketchannel = require "skynet.socketchannel" 15 | 16 | local _M = { 17 | _VERSION = "0.1" 18 | } 19 | _M.__index = _M 20 | 21 | local mt = {__index = _M} 22 | 23 | local LF = "\x0a" 24 | local EOL = "\x0d\x0a" 25 | local NULL_BYTE = "\x00" 26 | 27 | function _M:_build_frame(command, headers, body) 28 | local frame = {command, EOL} 29 | 30 | if body then 31 | headers["content-length"] = len(body) 32 | end 33 | 34 | for key, value in pairs(headers) do 35 | insert(frame, key) 36 | insert(frame, ":") 37 | insert(frame, value) 38 | insert(frame, EOL) 39 | end 40 | 41 | insert(frame, EOL) 42 | 43 | if body then 44 | insert(frame, body) 45 | end 46 | 47 | insert(frame, NULL_BYTE) 48 | insert(frame, EOL) 49 | return concat(frame, "") 50 | end 51 | 52 | local function __dispatch_resp(self) 53 | return function(sock) 54 | local frame 55 | if self.opts.trailing_lf == nil or self.opts.trailing_lf == true then 56 | frame = sock:readline(NULL_BYTE .. LF) 57 | else 58 | frame = sock:readline(NULL_BYTE) 59 | end 60 | 61 | if not frame then 62 | return false 63 | end 64 | 65 | -- We successfully received a frame, but it was an ERROR frame 66 | if sub(frame, 1, len("ERROR")) == "ERROR" then 67 | skynet.error("rabbitmq error:", frame) 68 | end 69 | skynet.error("resp frame:", frame) 70 | return true, frame 71 | end 72 | end 73 | 74 | function _M:_send_frame(frame) 75 | local dispatch_resp = __dispatch_resp(self) 76 | return self.__sock:request(frame, dispatch_resp) 77 | end 78 | 79 | local function rabbitmq_login(self) 80 | return function(sc) 81 | local headers = {} 82 | headers["accept-version"] = "1.2" 83 | headers["login"] = self.opts.username 84 | headers["passcode"] = self.opts.password 85 | headers["host"] = self.opts.vhost 86 | 87 | return self:_send_frame(self:_build_frame("CONNECT", headers, nil)) 88 | end 89 | end 90 | 91 | function _M.connect(conf, opts) 92 | if opts == nil then 93 | opts = {username = "guest", password = "guest", vhost = "/", trailing_lf = true} 94 | end 95 | 96 | local obj = { 97 | opts = opts 98 | } 99 | 100 | obj.__sock = 101 | socketchannel.channel { 102 | auth = rabbitmq_login(obj), 103 | host = conf.host or "127.0.0.1", 104 | port = conf.port or 61613, 105 | nodelay = true, 106 | overload = conf.overload 107 | } 108 | 109 | setmetatable(obj, _M) 110 | obj.__sock:connect(true) 111 | return obj 112 | end 113 | 114 | function _M:send(smsg, headers) 115 | local f = nil 116 | if headers["receipt"] ~= nil then 117 | f = __dispatch_resp(self) 118 | end 119 | return self.__sock:request(self:_build_frame("SEND", headers, smsg), f) 120 | end 121 | 122 | function _M:subscribe(headers, cb) 123 | self.__cb = cb 124 | return self:_send_frame(self:_build_frame("SUBSCRIBE", headers)) 125 | end 126 | 127 | function _M:unsubscribe(headers) 128 | return self:_send_frame(self:_build_frame("UNSUBSCRIBE", headers)) 129 | end 130 | 131 | function _M:receive() 132 | local so = self.__sock 133 | while so do 134 | local dispatch_resp = __dispatch_resp(self) 135 | local data, err = so:response(dispatch_resp) 136 | skynet.error("receive:", data, err) 137 | 138 | if not data then 139 | return nil, err 140 | end 141 | 142 | local idx = find(data, "\n\n", 2) 143 | self.__cb(sub(data, idx + 2)) 144 | end 145 | end 146 | 147 | function _M:close() 148 | if self.state then 149 | -- Graceful shutdown 150 | local headers = {} 151 | headers["receipt"] = "disconnect" 152 | self:_send_frame(self:_build_frame("DISCONNECT", headers, nil)) 153 | end 154 | 155 | self.__sock:close() 156 | setmetatable(self, nil) 157 | end 158 | 159 | return _M 160 | --------------------------------------------------------------------------------