Documentation for pulsar 0.9.2. For development docs, go here.

Source code for examples.djangoapp.djchat.views

import time

from pulsar import HttpException, task
from pulsar.apps import ws
from pulsar.apps.data import PubSubClient, create_store
from pulsar.utils.system import json
from pulsar.utils.security import random_string


def home(request):
    from django.shortcuts import render_to_response
    from django.template import RequestContext
    return render_to_response('home.html', {
        'HOST': request.get_host()
        }, RequestContext(request))


class ChatClient(PubSubClient):

    def __init__(self, websocket):
        self.joined = time.time()
        self.websocket = websocket
        self.websocket._chat_client = self

    def __call__(self, channel, message):
        # The message is an encoded JSON string
        self.websocket.write(message, opcode=1)


[docs]class Chat(ws.WS): ''':class:`.WS` handler managing the chat application.''' _store = None _pubsub = None _client = None
[docs] def get_pubsub(self, websocket): '''Create the pubsub handler if not already available''' if not self._store: cfg = websocket.cfg self._store = create_store(cfg.data_store) self._client = self._store.client() self._pubsub = self._store.pubsub() webchat = '%s:webchat' % cfg.exc_id chatuser = '%s:chatuser' % cfg.exc_id self._pubsub.subscribe(webchat, chatuser) return self._pubsub
@task
[docs] def on_open(self, websocket): '''A new websocket connection is established. Add it to the set of clients listening for messages. ''' self.get_pubsub(websocket).add_client(ChatClient(websocket)) user, _ = self.user(websocket) users_key = 'webchatusers:%s' % websocket.cfg.exc_id # add counter to users registered = yield self._client.hincrby(users_key, user, 1) if registered == 1: self.publish(websocket, 'chatuser', 'joined')
@task
[docs] def on_close(self, websocket): '''Leave the chat room ''' user, _ = self.user(websocket) users_key = 'webchatusers:%s' % websocket.cfg.exc_id registered = yield self._client.hincrby(users_key, user, -1) self.get_pubsub(websocket).remove_client(websocket._chat_client) if not registered: self.publish(websocket, 'chatuser', 'gone') if registered <= 0: self._client.hdel(users_key, user)
[docs] def on_message(self, websocket, msg): '''When a new message arrives, it publishes to all listening clients. ''' if msg: lines = [] for l in msg.split('\n'): l = l.strip() if l: lines.append(l) msg = ' '.join(lines) if msg: self.publish(websocket, 'webchat', msg)
def user(self, websocket): user = websocket.handshake.get('django.user') if user.is_authenticated(): return user.username, True else: session = websocket.handshake.get('django.session') user = session.get('chatuser') if not user: user = 'an_%s' % random_string(length=6).lower() session['chatuser'] = user return user, False def publish(self, websocket, channel, message=''): user, authenticated = self.user(websocket) msg = {'message': message, 'user': user, 'authenticated': authenticated, 'channel': channel} channel = '%s:%s' % (websocket.cfg.exc_id, channel) return self._pubsub.publish(channel, json.dumps(msg))
[docs]class middleware(object): '''Django middleware for serving the Chat websocket.''' def __init__(self): self._web_socket = ws.WebSocket('/message', Chat()) def process_request(self, request): from django.http import HttpResponse environ = request.META environ['django.user'] = request.user environ['django.session'] = request.session try: response = self._web_socket(environ) except HttpException as e: return HttpResponse(status=e.status) if response is not None: # we have a response, this is the websocket upgrade. # Convert to django response resp = HttpResponse(status=response.status_code, content_type=response.content_type) for header, value in response.headers: resp[header] = value return resp else: environ.pop('django.user') environ.pop('django.session')