def run(self):
"""Option to calling manually calling start()/stop(). This will start
the server and watch for signals to stop the server"""
self.server.start()
log.info(" ABCIServer started on port: {}".format(self.port))
# wait for interrupt
evt = Event()
gevent.signal(signal.SIGQUIT, evt.set)
gevent.signal(signal.SIGTERM, evt.set)
gevent.signal(signal.SIGINT, evt.set)
evt.wait()
log.info("Shutting down server")
self.server.stop()
# TM will spawn off 3 connections: mempool, consensus, query
# If an error happens in 1 it still leaves the others open which
# means you don't have all the connections available to TM
python类server()的实例源码
def __init__(
self,
host,
port,
socket=None,
protocol=None,
throttle_policy=DummyPolicy()):
self.protocol = protocol
if socket is not None:
self.server = DatagramServer(socket, handle=self.receive)
else:
self.server = DatagramServer((host, port), handle=self.receive)
self.host = self.server.server_host
self.port = self.server.server_port
self.throttle_policy = throttle_policy
def send(self, sender, host_port, bytes_):
""" Send `bytes_` to `host_port`.
Args:
sender (address): The address of the running node.
host_port (Tuple[(str, int)]): Tuple with the host name and port number.
bytes_ (bytes): The bytes that are going to be sent through the wire.
"""
sleep_timeout = self.throttle_policy.consume(1)
# Don't sleep if timeout is zero, otherwise a context-switch is done
# and the message is delayed, increasing it's latency
if sleep_timeout:
gevent.sleep(sleep_timeout)
if not hasattr(self.server, 'socket'):
raise RuntimeError('trying to send a message on a closed server')
self.server.sendto(bytes_, host_port)
# enable debugging using the DummyNetwork callbacks
DummyTransport.network.track_send(sender, host_port, bytes_)
def addQGreenlet(self, appName, greenlet):
"""
"""
if self.webserver == None:
return
qGreenletObject = greenlet()
if qGreenletObject.method == "":
raise RuntimeError("greenlet class needs to have a method")
if qGreenletObject.actor == "":
raise RuntimeError("greenlet class needs to have a actor")
qGreenletObject.server = self
self.webserver.addRoute(function=qGreenletObject.wscall,
appname=appName,
actor=qGreenletObject.actor,
method=qGreenletObject.method,
paramvalidation=qGreenletObject.paramvalidation,
paramdescription=qGreenletObject.paramdescription,
paramoptional=qGreenletObject.paramoptional,
description=qGreenletObject.description, auth=qGreenletObject.auth)
def update_environ(self):
"""
Called before the first request is handled to fill in WSGI environment values.
This includes getting the correct server name and port.
"""
address = self.address
if isinstance(address, tuple):
if 'SERVER_NAME' not in self.environ:
try:
name = socket.getfqdn(address[0])
except socket.error:
name = str(address[0])
if PY3 and not isinstance(name, str):
name = name.decode('ascii')
self.environ['SERVER_NAME'] = name
self.environ.setdefault('SERVER_PORT', str(address[1]))
else:
self.environ.setdefault('SERVER_NAME', '')
self.environ.setdefault('SERVER_PORT', '')
def update_environ(self):
"""
Called before the first request is handled to fill in WSGI environment values.
This includes getting the correct server name and port.
"""
address = self.address
if isinstance(address, tuple):
if 'SERVER_NAME' not in self.environ:
try:
name = socket.getfqdn(address[0])
except socket.error:
name = str(address[0])
if PY3 and not isinstance(name, str):
name = name.decode('ascii') # python 2 pylint:disable=redefined-variable-type
self.environ['SERVER_NAME'] = name
self.environ.setdefault('SERVER_PORT', str(address[1]))
else:
self.environ.setdefault('SERVER_NAME', '')
self.environ.setdefault('SERVER_PORT', '')
def _main():
# Provisional main handler, for quick tests, not production
# usage.
from gevent import monkey; monkey.patch_all()
import argparse
import importlib
parser = argparse.ArgumentParser()
parser.add_argument("app", help="dotted name of WSGI app callable [module:callable]")
parser.add_argument("-b", "--bind",
help="The socket to bind",
default=":8080")
args = parser.parse_args()
module_name, app_name = args.app.split(':')
module = importlib.import_module(module_name)
app = getattr(module, app_name)
bind = args.bind
server = WSGIServer(bind, app)
server.serve_forever()
def forward(source, dest, server):
try:
while True:
try:
data = source.recv(BUFFER_SIZE)
if not data:
break
dest.sendall(data)
except KeyboardInterrupt:
if not server.closed:
server.close()
break
except socket.error:
if not server.closed:
server.close()
break
finally:
source.close()
dest.close()
server = None
def forward(source, dest, server):
source_address = '%s:%s' % source.getpeername()[:2]
dest_address = '%s:%s' % dest.getpeername()[:2]
try:
while True:
try:
data = source.recv(1024)
log('%s->%s', source_address, dest_address)
if not data:
break
dest.sendall(data)
except KeyboardInterrupt:
if not server.closed:
server.close()
break
except socket.error:
if not server.closed:
server.close()
break
finally:
source.close()
dest.close()
server = None
def parseOptions():
'''
parse program parameters
'''
usage = 'usage: %prog [options]'
parser = optparse.OptionParser(usage=usage)
parser.add_option('--port', dest='port', metavar='PORT',
help='listen server port')
parser.add_option('--debug', dest='debug', action="store_true",
metavar='DEBUG', help='Debugging state')
parser.add_option('--host', dest='host', metavar='HOST',
help='host server address')
parser.add_option('--listen-udp', dest='listen_udp', metavar='UDPLISTEN',
help='Listen for local updates at UDP IP:PORT. Use with caution.')
parser.add_option('--send-udp', dest='send_udp', metavar='UDPSND',
help='Duplicate all updates to UDP "IP1:PORT1 IP2:PORT2 ..."')
options, args = parser.parse_args()
return options, args, parser
def main():
parser = argparse.ArgumentParser(description="Haproxy agent check service")
parser.add_argument("-c", "--config",
default="/etc/herald/config.yml",
type=str,
help="path to yaml configuraion file")
parser.add_argument("-b", "--bind",
default='0.0.0.0',
type=str,
help="listen address")
parser.add_argument("-p", "--port",
default=5555,
type=int,
help="listen port")
parser.add_argument("-l", "--loglevel",
default='info',
choices=['info', 'warn', 'debug', 'critical'],
type=str,
help="set logging level")
args = parser.parse_args()
setup_logging(args)
config = load_configuration(args.config)
all_plugins = load_all_plugins(config['plugins_dir'])
plugin = load_plugin(all_plugins, config['plugins'])
start_plugin(plugin)
server = start_server(args, config, plugin)
setup_handlers(server, plugin)
gevent.wait()
def drain( self ):
# Stop accepting new connections.
if self.server is not None:
self.server.close()
# Ask all the clients to nicely disconnect.
for aid, c in self.currentClients.items():
try:
c.sendFrame( HcpModuleId.HCP,
( rSequence().addInt8( Symbols.base.OPERATION,
HcpOperations.DISCONNECT ), ) )
except:
pass
# Wait for everyone to be out.
while 0 != self.nConnected:
self.log( "still %d clients connected" % self.nConnected )
self.sleep( 5 )
def drain( self ):
# Stop accepting new connections.
if self.server is not None:
self.server.close()
# Ask all the clients to nicely disconnect.
for aid, c in self.currentClients.items():
try:
c.sendFrame( HcpModuleId.HCP,
( rSequence().addInt8( Symbols.base.OPERATION,
HcpOperations.DISCONNECT ), ) )
except:
pass
# Wait for everyone to be out.
while 0 != self.nConnected:
self.log( "still %d clients connected" % self.nConnected )
self.sleep( 5 )
def forward( source, dest, address, server ):
buff = bytearray( 4096 )
mv_buffer = memoryview( buff )
try:
while True:
nReceived = source.recv_into( buff )
if 0 == nReceived:
break
dest.sendall( mv_buffer[ : nReceived ] )
except:
pass
finally:
print( "Closed from %s" % str( address ) )
try:
source.close()
except:
pass
try:
dest.close()
except:
pass
server = None
def update_environ(self):
"""
Called before the first request is handled to fill in WSGI environment values.
This includes getting the correct server name and port.
"""
address = self.address
if isinstance(address, tuple):
if 'SERVER_NAME' not in self.environ:
try:
name = socket.getfqdn(address[0])
except socket.error:
name = str(address[0])
if PY3 and not isinstance(name, str):
name = name.decode('ascii') # python 2 pylint:disable=redefined-variable-type
self.environ['SERVER_NAME'] = name
self.environ.setdefault('SERVER_PORT', str(address[1]))
else:
self.environ.setdefault('SERVER_NAME', '')
self.environ.setdefault('SERVER_PORT', '')
def _main():
# Provisional main handler, for quick tests, not production
# usage.
from gevent import monkey; monkey.patch_all()
import argparse
import importlib
parser = argparse.ArgumentParser()
parser.add_argument("app", help="dotted name of WSGI app callable [module:callable]")
parser.add_argument("-b", "--bind",
help="The socket to bind",
default=":8080")
args = parser.parse_args()
module_name, app_name = args.app.split(':')
module = importlib.import_module(module_name)
app = getattr(module, app_name)
bind = args.bind
server = WSGIServer(bind, app)
server.serve_forever()
def run(self, interactive=False):
"""Run the server
Params:
interactive -- Start in interactive mode (Note: Does not work with web server)
"""
#tdaemon = torrent.start()
try:
self._start(not interactive)
if interactive:
self.interactive()
except KeyboardInterrupt:
pass
self._server.stop()
# torrent.stop()
# tdaemon.join()
log.i("Server shutting down.", stdout=True)
def update_environ(self):
"""
Called before the first request is handled to fill in WSGI environment values.
This includes getting the correct server name and port.
"""
address = self.address
if isinstance(address, tuple):
if 'SERVER_NAME' not in self.environ:
try:
name = socket.getfqdn(address[0])
except socket.error:
name = str(address[0])
if PY3 and not isinstance(name, str):
name = name.decode('ascii')
self.environ['SERVER_NAME'] = name
self.environ.setdefault('SERVER_PORT', str(address[1]))
else:
self.environ.setdefault('SERVER_NAME', '')
self.environ.setdefault('SERVER_PORT', '')
def __init__(self, port=46658, app=None):
if not app or not isinstance(app, BaseApplication):
log.error("Application missing or not an instance of Base Application")
raise TypeError("Application missing or not an instance of Base Application")
self.port = port
self.protocol = ProtocolHandler(app)
self.server = StreamServer(('0.0.0.0', port), handle=self.__handle_connection)
def start(self):
self.server.start()
log.info(" ABCIServer started on port: {}".format(self.port))
def stop(self):
log.info("Shutting down server")
self.server.stop()
def start(self):
self.running = True
CryptConnection.manager.loadCerts()
self.log.debug("Binding to: %s:%s, (msgpack: %s), supported crypt: %s" % (
self.ip, self.port,
".".join(map(str, msgpack.version)), CryptConnection.manager.crypt_supported)
)
try:
self.stream_server.serve_forever() # Start normal connection server
except Exception, err:
self.log.info("StreamServer bind error, must be running already: %s" % err)
def server():
ss = StreamServer(('localhost', PORT), serve).serve_forever()
def stop(self):
self.server.stop()
# Calling `.close()` on a gevent socket doesn't actually close the underlying os socket
# so we do that ourselves here.
# See: https://github.com/gevent/gevent/blob/master/src/gevent/_socket2.py#L208
# and: https://groups.google.com/forum/#!msg/gevent/Ro8lRra3nH0/ZENgEXrr6M0J
try:
self.server._socket.close()
except socket.error:
pass
def stop_accepting(self):
self.server.stop_accepting()
def start(self):
assert not self.server.started
# server.stop() clears the handle, since this may be a restart the
# handle must always be set
self.server.set_handle(self.receive)
self.server.start()
def __init__(self, socket, address, server, rfile=None):
self.socket = socket
self.client_address = address
self.server = server
if rfile is None:
self.rfile = socket.makefile('rb', -1)
else:
self.rfile = rfile
def log_request(self):
log = self.server.log
if log:
log.write(self.format_request() + '\n')
def handle_error(self, type, value, tb):
if not issubclass(type, GreenletExit):
self.server.loop.handle_error(self.environ, type, value, tb)
del tb
if self.response_length:
self.close_connection = True
else:
self.start_response(_INTERNAL_ERROR_STATUS, _INTERNAL_ERROR_HEADERS[:])
self.write(_INTERNAL_ERROR_BODY)
def log_request(self):
log = self.server.log
if log:
log.write(self.format_request() + '\n')