source:
ralphm-patches/c2s_server_factory.patch
@
57:0d8b6cf41728
Last change on this file since 57:0d8b6cf41728 was 57:0d8b6cf41728, checked in by Ralph Meijer <ralphm@…>, 10 years ago | |
---|---|
File size: 4.0 KB |
-
wokkel/client.py
# HG changeset patch # Parent d76497171af8f3acf1efd2c8433fbdc3c4a55f92 Add factory for accepting client connections. The new XMPPC2SServerFactory is a server factory for accepting client connections. It uses `XMPPClientListenAuthenticator` to perform the steps for authentication and binding of a resource, and keeps a list of all streams. Upon loss of the connection, the service is called with `unbindResource`. Received stanzas cause the service's `onElement` to be called. The factory has a `deliverStanza` method to deliver stanzas to a particular recipient. This is used for stanzas that have different recipient addressing than the actual recipient (for presence and messages from a different (or no) resource). TODO: * Add docstrings. * Add tests. diff -r d76497171af8 wokkel/client.py
a b 20 20 from twisted.words.xish import domish 21 21 22 22 from wokkel import generic 23 from wokkel.compat import XmlStreamServerFactory 23 24 from wokkel.subprotocols import StreamManager 24 25 25 26 NS_CLIENT = 'jabber:client' … … 347 348 348 349 349 350 351 class RecipientUnavailable(Exception): 352 """ 353 The addressed entity is not, or no longer, available. 354 """ 355 356 357 358 class XMPPC2SServerFactory(XmlStreamServerFactory): 359 360 def __init__(self, service): 361 self.service = service 362 363 def authenticatorFactory(): 364 return XMPPClientListenAuthenticator(service) 365 366 XmlStreamServerFactory.__init__(self, authenticatorFactory) 367 self.addBootstrap(xmlstream.STREAM_CONNECTED_EVENT, 368 self.onConnectionMade) 369 self.addBootstrap(xmlstream.STREAM_AUTHD_EVENT, 370 self.onAuthenticated) 371 372 self.serial = 0 373 self.streams = {} 374 375 376 def onConnectionMade(self, xs): 377 """ 378 Called when a client-to-server connection was made. 379 380 This enables traffic debugging on incoming streams. 381 """ 382 xs.serial = self.serial 383 self.serial += 1 384 385 log.msg("Client connection %d made" % xs.serial) 386 387 def logDataIn(buf): 388 log.msg("RECV (%d): %r" % (xs.serial, buf)) 389 390 def logDataOut(buf): 391 log.msg("SEND (%d): %r" % (xs.serial, buf)) 392 393 if self.logTraffic: 394 xs.rawDataInFn = logDataIn 395 xs.rawDataOutFn = logDataOut 396 397 xs.addObserver(xmlstream.STREAM_ERROR_EVENT, self.onError) 398 399 400 def onAuthenticated(self, xs): 401 log.msg("Client connection %d authenticated" % xs.serial) 402 403 xs.addObserver(xmlstream.STREAM_END_EVENT, self.onConnectionLost, 404 0, xs) 405 xs.addObserver('/*', self.onElement, 0, xs) 406 407 # Record this stream as bound to the authenticated JID 408 self.streams[xs.otherEntity] = xs 409 410 411 def onConnectionLost(self, xs, reason): 412 log.msg("Client connection %d disconnected" % xs.serial) 413 414 entity = xs.otherEntity 415 self.service.unbindResource(entity.user, 416 entity.host, 417 entity.resource, 418 reason) 419 420 # If the lost connections had been bound, remove the reference 421 if xs.otherEntity in self.streams: 422 del self.streams[xs.otherEntity] 423 424 425 def onError(self, reason): 426 log.err(reason, "Stream Error") 427 428 429 def onElement(self, xs, stanza): 430 """ 431 Called when an element was received from one of the connected streams. 432 433 """ 434 if stanza.handled: 435 return 436 else: 437 self.service.onElement(stanza, xs.otherEntity) 438 439 440 def deliverStanza(self, element, recipient): 441 if recipient in self.streams: 442 self.streams[recipient].send(element) 443 else: 444 raise RecipientUnavailable(u"There is no connection for %s" % 445 recipient.full())
Note: See TracBrowser
for help on using the repository browser.