Error on AMQP socket deconnectionn <0.18789.4>: enotconn (socket is not connected)

puka&CloseThis is an old version. Latest version is
Dark themeLight theme&
import errno
import logging
import select
import socket
import struct
import time
import urllib
from . import urlparse
from . import channel
from . import exceptions
from . import machine
from . import simplebuffer
from . import spec
from . import promise
log = logging.getLogger('puka')
class Connection(object):
frame_max = 131072
def __init__(self, amqp_url='amqp:///', pubacks=None, client_properties=None, heartbeat=0):
self.pubacks = pubacks
self.channels = channel.ChannelCollection()
self.promises = promise.PromiseCollection(self)
(self.username, self.password, self.vhost, self.host, self.port) = \
parse_amqp_url(str(amqp_url))
self.client_properties = client_properties
self.heartbeat = heartbeat
def _init_buffers(self):
self.recv_buf = simplebuffer.SimpleBuffer()
self.recv_need = 8
self.send_buf = simplebuffer.SimpleBuffer()
def fileno(self):
return self.sd.fileno()
def socket(self):
return self.sd
def _connect(self):
self._handle_read = self._handle_conn_read
self._init_buffers()
addrinfo = socket.getaddrinfo(self.host, self.port, socket.AF_INET6, socket.SOCK_STREAM)
except socket.gaierror:
addrinfo = socket.getaddrinfo(self.host, self.port, socket.AF_INET, socket.SOCK_STREAM)
(family, socktype, proto, canonname, sockaddr) = addrinfo[0]
self.sd = socket.socket(family, socktype, proto)
self.sd.setblocking(False)
set_ridiculously_high_buffers(self.sd)
set_close_exec(self.sd)
self.sd.connect(sockaddr)
except socket.error, e:
if e.errno not in (errno.EINPROGRESS, errno.EWOULDBLOCK):
return machine.connection_handshake(self)
def on_read(self):
r = self.sd.recv(131072)
except socket.error, e:
if e.errno == errno.EAGAIN:
if len(r) == 0:
# a = self.sd.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
self._shutdown(exceptions.mark_frame(spec.Frame(),
exceptions.ConnectionBroken()))
self.recv_buf.write(r)
if len(self.recv_buf) &= self.recv_need:
data = self.recv_buf.read()
offset = 0
while len(data) - offset &= self.recv_need:
offset, self.recv_need = \
self._handle_read(data, offset)
self.recv_buf.consume(offset)
def _handle_conn_read(self, data, offset):
self._handle_read = self._handle_frame_read
if data[offset:].startswith('AMQP'):
a,b,c,d = struct.unpack('!BBBB', data[offset+4:offset+4+4])
self._shutdown(exceptions.mark_frame(
spec.Frame(),
exceptions.UnsupportedProtocol(&%s.%s.%s.%s& % (a,b,c,d))))
return 0,0
return self._handle_frame_read(data, offset)
def _handle_frame_read(self, data, start_offset):
offset = start_offset
if len(data)-start_offset & 8:
return start_offset, 8
frame_type, channel, payload_size = \
struct.unpack_from('!BHI', data, offset)
offset += 7
if len(data)-start_offset & 8+payload_size:
return start_offset, 8+payload_size
assert data[offset+payload_size] == '\xCE'
if frame_type == 0x01: # Method frame
method_id, = struct.unpack_from('!I', data, offset)
offset += 4
frame, offset = spec.METHODS[method_id](data, offset)
self.channels.channels[channel].inbound_method(frame)
elif frame_type == 0x02: # header frame
(class_id, body_size) = struct.unpack_from('!HxxQ', data, offset)
offset += 12
props, offset = spec.PROPS[class_id](data, offset)
self.channels.channels[channel].inbound_props(body_size, props)
elif frame_type == 0x03: # body frame
body_chunk = str(data[offset : offset+payload_size])
self.channels.channels[channel].inbound_body(body_chunk)
offset += len(body_chunk)
elif frame_type == 0x08: # heartbeat frame
# One corner of the spec doc says this will be 0x04, most
# says 0x08 which seems to be what's been implemented by
# RabbitMQ at least.
# Got heartbeat, respond with one.
# It seems likely this logic is slightly incorrect. We're
# getting a heartbeat because we asked for one from the
# server. At connection setup it probably asked us for one
# as well with the same timeout.
We're using the server
# heartbeat as a trigger instead of setting up a separate
# heartbeat cycler.
self._send_frames(channel_number=0, frames=[(0x08, '')])
assert False, &Unknown frame type 0x%x& % frame_type
offset += 1 # '\xCE'
assert offset == start_offset+8+payload_size
return offset, 8
def _send(self, data):
# Do not try to write straightaway, better wait for more data.
self.send_buf.write(data)
def _send_frames(self, channel_number, frames):
self._send( ''.join([''.join((struct.pack('!BHI',
frame_type,
channel_number,
len(payload)),
payload, '\xCE')) \
for frame_type, payload in frames]) )
def needs_write(self):
return bool(self.send_buf)
def on_write(self):
# On windows socket.send blows up if the buffer is too large.
r = self.sd.send(self.send_buf.read(128*1024))
except socket.error, e:
if e.errno == errno.EAGAIN:
self.send_buf.consume(r)
def _tune_frame_max(self, new_frame_max):
new_frame_max = new_frame_max if new_frame_max != 0 else 2**19
self.frame_max = min(self.frame_max, new_frame_max)
return self.frame_max
def wait(self, promise_numbers, timeout=None, raise_errors=True):
'''
Wait for selected promises. Exit after promise runs a callback.
'''
if timeout is not None:
t1 = time.time() + timeout
if isinstance(promise_numbers, int):
promise_numbers = [promise_numbers]
promise_numbers = set(promise_numbers)
# Try flushing the write buffer before entering the loop, we
# may as well return soon, and the user has no way to figure
# out if the write buffer was flushed or not - (ie: did the
# wait run select() or not)
# This is problem is especially painful with regard to
# async messages, like basic_ack. See #3.
# Additionally, during the first round trip on windows - when
# the connection is being established, the socket may not yet
# be in the connected state - swallow an error in that case.
self.on_write()
except socket.error, e:
if e.errno != errno.ENOTCONN:
while True:
while True:
ready = promise_numbers & self.promises.ready
if not ready:
promise_number = ready.pop()
return self.promises.run_callback(promise_number,
raise_errors=raise_errors)
if timeout is not None:
t0 = time.time()
td = t1 - t0
if td & 0:
r, w, e = select.select([self],
[self] if self.needs_write() else [],
if r or e:
self.on_read()
self.on_write()
if not r and not e and not w:
return None
def wait_for_any(self):
return self.loop()
def wait_for_all(self, promise_list, raise_errors=True):
for promise in promise_list:
self.wait(promise, raise_errors=raise_errors)
def loop(self, timeout=None):
'''
Wait for any promise. Block forever.
'''
if timeout is not None:
t1 = time.time() + timeout
self._loop_break = False
while True:
self.run_any_callbacks()
if self._loop_break:
if timeout is not None:
t0 = time.time()
td = t1 - t0
if td & 0:
r, w, e = select.select([self],
[self] if self.needs_write() else [],
if r or e:
self.on_read()
self.on_write()
# Try flushing the write buffer just after the loop. The user
# has no way to figure out if the buffer was flushed or
# not. (ie: if the loop() require waiting on for data or not).
self.on_write()
def loop_break(self):
self._loop_break = True
def run_any_callbacks(self):
'''
Run any callbacks, any promises, but do not block.
'''
while self.promises.ready:
[self.promises.run_callback(promise, raise_errors=False) \
for promise in list(self.promises.ready)]
def _shutdown(self, result):
# Cancel all events.
for promise in self.promises.all():
# It's possible that a promise may be already `done` but still not
# removed. For example due to `refcnt`. In that case don't run
# callbacks.
if promise.to_be_released is False:
promise.done(result)
# And kill the socket
self.sd.shutdown(socket.SHUT_RDWR)
except socket.error, e:
if e.errno is not errno.ENOTCONN: raise
self.sd.close()
self.sd = None
# Sending is illegal
self.send_buf = None
def _close(self):
return machine.connection_close(self)
def set_callback(self, promise_number, callback):
promise = self.promises.by_number(promise_number)
promise.user_callback = callback
def parse_amqp_url(amqp_url):
'''
&&& parse_amqp_url('amqp:///')
('guest', 'guest', '/', 'localhost', 5672)
&&& parse_amqp_url('amqp://a:b@c:1/d')
('a', 'b', 'd', 'c', 1)
&&& parse_amqp_url('amqp://g%20uest:g%20uest@host/vho%20st')
('g uest', 'g uest', 'vho st', 'host', 5672)
&&& parse_amqp_url('http://asd')
Traceback (most recent call last):
AssertionError: Only amqp:// protocol supported.
&&& parse_amqp_url('amqp://host/%2f')
('guest', 'guest', '/', 'host', 5672)
&&& parse_amqp_url('amqp://host/%2fabc')
('guest', 'guest', '/abc', 'host', 5672)
&&& parse_amqp_url('amqp://host/')
('guest', 'guest', '/', 'host', 5672)
&&& parse_amqp_url('amqp://host')
('guest', 'guest', '/', 'host', 5672)
&&& parse_amqp_url('amqp://user:pass@host:10000/vhost')
('user', 'pass', 'vhost', 'host', 10000)
&&& parse_amqp_url('amqp://user%61:%61pass@ho%61st:10000/v%2fhost')
('usera', 'apass', 'v/host', 'hoast', 10000)
&&& parse_amqp_url('amqp://')
('guest', 'guest', '/', 'localhost', 5672)
&&& parse_amqp_url('amqp://:@/') # this is a violation, vhost should be=''
('', '', '/', 'localhost', 5672)
&&& parse_amqp_url('amqp://user@/')
('user', 'guest', '/', 'localhost', 5672)
&&& parse_amqp_url('amqp://user:@/')
('user', '', '/', 'localhost', 5672)
&&& parse_amqp_url('amqp://host')
('guest', 'guest', '/', 'host', 5672)
&&& parse_amqp_url('amqp:///vhost')
('guest', 'guest', 'vhost', 'localhost', 5672)
&&& parse_amqp_url('amqp://host/')
('guest', 'guest', '/', 'host', 5672)
&&& parse_amqp_url('amqp://host/%2f%2f')
('guest', 'guest', '//', 'host', 5672)
&&& parse_amqp_url('amqp://[::1]')
('guest', 'guest', '/', '::1', 5672)
'''
assert amqp_url.startswith('amqp://'), &Only amqp:// protocol supported.&
# urlsplit doesn't know how to parse query when scheme is amqp,
# we need to pretend we're http'
o = urlparse.urlsplit('http://' + amqp_url[len('amqp://'):])
username = urllib.unquote(o.username) if o.username is not None else 'guest'
password = urllib.unquote(o.password) if o.password is not None else 'guest'
path = o.path[1:] if o.path.startswith('/') else o.path
# We do not support empty vhost case. Empty vhost is treated as
# '/'. This is mostly for backwards compatibility, and the fact
# that empty vhost is not very useful.
vhost = urllib.unquote(path) if path else '/'
host = urllib.unquote(o.hostname) if o.hostname else 'localhost'
port = o.port if o.port else 5672
return (username, password, vhost, host, port)
def set_ridiculously_high_buffers(sd):
'''
Set large tcp/ip buffers kernel. Let's move the complexity
to the operating system! That's a wonderful idea!
'''
for flag in [socket.SO_SNDBUF, socket.SO_RCVBUF]:
for i in range(10):
bef = sd.getsockopt(socket.SOL_SOCKET, flag)
sd.setsockopt(socket.SOL_SOCKET, flag, bef*2)
except socket.error:
aft = sd.getsockopt(socket.SOL_SOCKET, flag)
if aft &= bef or aft &= :
def set_close_exec(fd):
'''
exec functions (e.g. subprocess.Popen) by default force the child
process to inherit all file handles which can result in stuck
connections and unacknowledged messages. Setting FD_CLOEXEC forces
the handles to be closed first.
'''
import fcntl
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
except ImportError:502 Bad Gateway
502 Bad GatewayRabbitMQ 3.4.0 发布下载,AMQP 消息服务器_Linux新闻_Linux公社-Linux系统门户网站
你好,游客
RabbitMQ 3.4.0 发布下载,AMQP 消息服务器
来源:oschina.net&
作者:Linux
基于Erlang的高级消息队列RabbitMQ 3.4.0发布.新产品系列。。之前版本的3.3.5.遗留产品3.2.4/3.1.5 在高级消息队列里,RabbitMQ应该最主流的。
5.6 安装RabbitMQ
RabbitMQ客户端C++安装详细记录
用Python尝试RabbitMQ
RabbitMQ集群环境生产实例部署
下PHP + RabbitMQ使用
在CentOS上安装RabbitMQ流程
此版本的新特性主要有:
1. RPC客户端快速应答机制。2. 可监控和限制队列字节长度。3. 无须重启即可激活或卸下插件。4. 可从持久化数据中恢复崩溃队 列。5. 允许.Net客户端网络中断后自动重连。6. 缺省不再支持SSL V3防止POODLE攻击。7. SSL握手超时可配置。8. 新的rabbitmq-plugins set子命令。
完全改进:
Release:&RabbitMQ&3.4.0
Security&Fixes
==============
management&plugin
-----------------
26414&do&not&trust&X-Forwarded-For&header&when&enforcing&'loopback_users'
26419&disable&SSLv3&by&default&to&prevent&the&POODLE&attack
Release&Highlights
==================
26354&prevent&force_event_refresh&message&from&killing&connections&that&have
& & & not&fully&started&(since&3.3.0)
26347&ensure&bindings&are&deleted&when&deleting&queue&records&as&part
& & & of&rabbitmqctl&forget_cluster_node&(since&3.0.3)
26341&add&assertions&to&prevent&silent&failure&from&DETS&errors&in
& & & rabbit_recovery_terms&(since&3.3.0)
26171&prevent&crash&in&rare&conditions&in&gm:find_member_or_blank/2&during
& & & slave&startup&(since&2.6.0)
26368&prevent&autoheal&from&hanging&when&loser&shuts&down&before&the&winner
& & & learns&it&is&the&winner&(since&3.1.0)
25850&prevent&excessive&binary&memory&use&when&accepting&or&delivering
& & & large&messages&at&high&speed&(since&1.0.0)
26230&ensure&exchanges&and&queues&are&federated&appropriately&when
& & & created&when&policy&exists&to&make&them&so&but&the&plugin&is
& & & not&enabled&(since&3.0.0)
26389&prevent&consumer&utilisation&getting&stuck&at&0%&after&busy&queue
& & & goes&idle&(since&3.3.0)
26370&prevent&"rabbitmqctl&cluster_status"&from&breaking&the&database
& & & if&invoked&at&the&wrong&point&during&first&startup&(since&3.0.0)
26295&ensure&"rabbitmqctl&wait"&waits&for&plugins&to&start
26336&fix&logging&when&cluster&auto-config&fails&(since&3.0.0)
26338&log&enotconn&as&'connection_closed_abruptly',&not&an&internal
& & & error&(since&1.0.0)
26343&fix&warning&about&missing&behaviour_info/1&in&supervisor2&with
& & & older&Erlang&(since&3.2.0)
26363&ensure&cluster&auto-config&does&not&try&to&cluster&with&nodes
& & & which&have&had&"rabbitmqctl&stop_app"&invoked&(since&3.0.0)
26378&fix&compilation&warnings&about&conflicting&behaviours&(since&2.6.0)
26386&ensure&broker&starts&even&if&vhost&pointed&to&by&default_vhost
& & & config&item&has&been&deleted&(since&1.0.0)
26404&prevent&queue&synchronisation&from&hanging&if&there&is&a&very
& & & short&partition&just&as&it&starts&(since&3.1.0)
enhancements
21446&allow&crashing&queue&processes&to&recover,&using&persistent&data
& & & if&present
25813&provide&fast&direct&route&for&RPC&replies
& & & & (see&/direct-reply-to.html)
24926&allow&plugins&to&be&enabled&/&disabled&without&restarting&the&server
25884&add&argument&and&policy&to&limit&queue&length&in&bytes
26150&prevent&clean&master&shutdown&from&promoting&unsynchronised
& & & slaves&and&thus&losing&&add&ha-promote-on-shutdown
& & & to&configure
26151&make&queues&located&on&down&cluster&nodes&visible&in&"rabbitmqctl
& & & list_queues"
26213&prevent&undefined&behaviour&during&partial&partitions&by
& & & promoting&them&to&full&ones
26254&allow&"rabbitmqctl_forget_cluster_node"&to&promote&mirror&queue&slaves
& & & that&are&down&and&thus&recover&from&loss&of&a&node&containing&masters
& & & after&it&was&the&last&node&to&stop
26256&add&"rabbitmqctl&force_boot"&command&to&allow&administrator&to
& & & override&RabbitMQ's&idea&of&the&last&node&to&shut&down
26307&add&messages_{ready,unacknowledged}_ram&/&messages_ram&/
& & & messages_persistent&queue&info&keys
25666&/&26339&add&message_bytes&/&message_bytes_{ready,unacknowledged,
& & & ram,persistent}&queue&info&keys
25214&improve&robustness&in&the&face&of&stray&messages&from&Mnesia&after
& & & partitions
25279&make&SSL&handshake&timeout&configurable
25678&make&mnesia&table&loading&timeout&configurable
26148&add&username&and&vhost&to&amqp_error&log&messages
26169&add&username&/&connection&information&to&firehose&trace&messages
26242&improve&clarity&of&rabbitmqctl&error&messages&when&stop_app&has&been
& & & invoked
26225&provide&connection&age&in&rabbitmqctl&list_connections
25446&add&"rabbitmq-plugins&set"&subcommand
25824&/&26398&provide&a&summary&of&binary&memory&use
26397&split&out&memory&used&by&slaves&vs&masters&/&unmirrored&in&the
& & & memory&summary
26401&split&out&memory&used&by&connection&readers&/&writers&/&channels&/&other
& & & in&the&memory&summary
26192&improve&usability&of&"rabbitmqctl&remove_cluster_node&--offline"&by
& & & not&requiring&the&user&to&start&a&node&with&RABBITMQ_NODE_ONLY
18626&add&RABBITMQ_USE_LONGNAME&(with&thanks&to&Marcos&Diez)
26204&allow&message&TTL&and&queue&expiry&times&above&(2^32)-1&milliseconds
26211&fix&use&of&type&specifications&deprecated&in&Erlang&17
26366&improve&error&messages&when&queue&/&exchange&equivalence&checks&fail
26387&use&new&strange&way&to&determine&OTP&minor&version&number
26394&add&cluster&heartbeat&messages&at&a&faster&rate&than&net_ticktime
26406&add&environment&for&plugins&and&non-RabbitMQ&apps&to&"rabbitmqctl
& & & environment"
25848&warn&if&RABBITMQ_SERVER_ERL_ARGS&set&in&a&way&that&will&lead&to
& & & poor&performance
25454&warn&if&rabbitmq-plugins&and&rabbitmq-server&disagree&on&the
& & & location&of&the&enabled_plugins&file
26221&improve&performance&of&queue.declare{nowait=true}
building&&&packaging
--------------------
enhancements
26344&ensure&missing&config&file&is&correctly&logged&in&.deb&/&RPM
& & & (since&3.3.0)
26154&switch&standalone&OS&X&build&to&use&Erlang&17.1
26040&add&missing&BuildRequires&to&RPM&spec&(since&1.8.0)
26411&fix&warning&on&Debian&build&clean&due&to&deleted&files
management&plugin
-----------------
enhancements
26107&provide&(and&default&to)&mode&where&we&maintain&message&rates
& & & only&per&object&(queue,&exchange&etc)&not&per&object
& & & pair&(queue-&channel&etc)&to&save&memory
26174&improve&responsiveness&of&management&API&under&load
25329&maintain&history&and&draw&charts&for&some&per-node&stats
& & & (memory,&disk&space&etc)
25470&provide&UI&to&show&/&hide&series&in&charts&in&the&web&UI
26382&provide&UI&to&show&/&hide&columns&columns&in&the&web&UI
26225&provide&connection&age&in&connection&list
25824&provide&a&summary&of&binary&memory&use
26151&make&queues&located&on&down&cluster&nodes&visible&in&queue&list
23724&provide&API&to&list&all&consumers
26340&redesigned,&more&concise&interface&for&queue&/&exchange&/
& & & policy&arguments
26193&display&locations&of&configuration,&database&and&logs&in&management
26193&detect&and&warn&on&mismatched&net_ticktime&setting
26235&show&enabled&plugins&in&management
25984&switch&to&HTML5&local&storage&where&available,&ensure
& & & multiple&web&UIs&on&same&host&do&not&share&login
26358&support&setting&message&properties&with&"rabbitmqadmin&publish"
26390&ensure&all&charts&have&the&same&time&range
26391&make&"rabbitmqadmin&list"&restrict&to&a&default&set&of&columns
26399&ensure&statistics&do&not&depend&on&erlang:now/0&being&in&sync&with
& & & os:timestamp/0&(since&3.2.0)
shovel&plugin
-------------
enhancements
26239&allow&dynamic&shovels&to&set&message&properties&like&static
& & & ones&do,&and&allow&static&shovels&to&use&add_forward_headers&like
& & & dynamic&ones&do
LDAP&plugin
-----------
enhancements
26275&support&LDAP&connections&using&StartTLS&(requires&Erlang&R16B03&or&later)
tracing&plugin
--------------
enhancements
26357&add&milliseconds&to&timestamps
STOMP&plugin
------------
enhancements
26306&add&flow&control&for&message&deliveries&through&STOMP;&greatly&reduces
& & & memory&use&when&slow&consumers&without&prefetch-count&connect&to&a
& & & large&/&fast&moving&queue
26243&ensure&all&stomp-named&queues&are&named&"stomp-*"
26266&support&"requeue"&header&on&NACK&frames
MQTT&plugin
-----------
enhancements
26330&add&flow&control&for&message&deliveries&through&MQTT;&greatly&reduces
& & & memory&use&when&slow&consumers&without&prefetch-count&connect&to&a
& & & large&/&fast&moving&queue
26356&fix&incorrect&reporting&of&MQTT&protocol&version&when&using&MQTT&3.1.1
Web-STOMP&plugin
----------------
enhancements
26392&don't&depend&on&the&SockJS&CDN
java&client
-----------
enhancements
26402&provide&a&means&to&configure&the&time&given&to&slow&consumers
& & & to&continue&consuming&internally&queued&messages&after&the
& & & connection&closes
26359&add&listeners&for&queue&name&changes&during&recovery
26207&add&APIs&to&make&methods&easier&to&use&in&nowait&mode
26121&add&--randomRoutingKey&flag&to&PerfTest
26091&add&--consumerRate&flag&to&PerfTest
26348&make&ConnectionFactory's&networkRecoveryInterval&property&into&a&long
26364&clean&up&client-side&references&to&auto-deleted&queues&in&the
& & & common&case&(since&3.3.0)
26374&limit&size&of&WorkPool&queues,&thus&prevent&slow&consumer&with&no
& & & prefetch&limit&from&consuming&unbounded&memory&(since&2.7.0)
26413&prevent&duplicate&connection&recovery&listeners&from&being
& & & registered&(since&3.3.0)
dependency&change
26095&drop&support&for&Java&1.5
licencing&change
24543&make&the&Java&client&additionally&avaliable&under&the&ASL2
.net&client
-----------
enhancements
26130&automatic&connection&recovery&similar&to&that&of&the&Java&client
26208&add&APIs&to&make&methods&easier&to&use&in&nowait&mode
26324&introduce&an&interface&for&ConnectionFactory
26334&set&up&stream&timeouts&as&early&as&possible&(thanks&to&John&Oliver)
26199&allow&IO&and&heartbeat&to&be&background&threads
25525&allow&Subscription&class&to&set&explicit&consumer&tag
26097&add&support&for&nack&/&reject&in&Subscription
26122&remove&unnecessary&lock&in&Subscription
feature&removal
26131&/&26132&remove&support&for&versions&of&AMQP&prior&to&0-9-1
26133&remove&redirect&following
erlang&client
-------------
enhancements
26166&allow&default&ssl&options&to&be&provided&in&the&configuration&file
26418&ensure&writer&death&is&detected&in&direct&connections&(since&3.2.0)
& & & (with&thanks&to&Christopher&Faulet)
26346&ensure&amqp_rpc_client&uses&exclusive,&autodelete&response
& & & queues&(since&1.3.0)
下载:/releases/rabbitmq-server/v3.4.0/rabbitmq-server-3.4.0.tar.gz
RabbitMQ 的详细介绍:RabbitMQ 的下载地址:
本文永久更新链接地址:
相关资讯 & & &
& (07月28日)
& (07月07日)
& (07月30日)
& (07月15日)
& (06月22日)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款

我要回帖

更多关于 amqpconnection 的文章

 

随机推荐