tornado websocket编程 : 简单购物车改进
上面例子显然有个问题:无法知道是哪些用户下了订单/取消订单。现在我们对其相关的修改
——记录用户,使其更加像一个真实的购物车应用。
可选的解决方案:
1. 客户端连接服务端时发送一个session,WebSocket类中添加一个成员变量记录客户端
session
2. 服务端WebSocket中on_open方法中调用request相关属性
在这个demo中使用方案2,至于原因呢,只要是想展示下客户端向服务端send消息的一些细
节。
修改cart.py
(如无说明,则只贴出相关修改,没贴出来部分表示没有修改, 下同)
# 引用两个新模块
from uuid import uuid4 as uuid
import json
修改IndexHandler的get方法
class Index(tornado.web.RequestHandler):
def get(self):
context = {
'total': self.application.cart.total,
# 在template渲染session数据
session': uuid()
}
self.render('cart.html', **context)
实现CartStatusHandler中on_message方法,用以处理客户端发送的数据
class CartStatusHandler(tornado.websocket.WebSocketHandler):
# 添加成员变量, 用以记录客户端发送的session
session = ''
# 不再在连接时注册
def open(self):
pass
def on_close(self):
self.application.cart.unregister(self)
# 接收客户端数据,当客户端发送的数据中的status为register时注册到Cart实例中
def on_message(self, message):
data = json.loads(message)
self.session = data.get('session')
if data.get('status') == 'connected':
if not data.get('session') == '':
# 注意此处修改!
self.application.cart.register(self)
def callback(self, customer, count):
context = {
'customer': customer,
'count': count
}
self.write_message(json.dumps(context))
修改Cart
(由于修改过多,此处贴出完整修改)
class Cart(object):
# 记录client实例
# 注册/取消注册/发送数据方法时调用client实例方法和属性
clients = []
def __init__(self):
self.__total = 100
def register(self, client):
self.clients.append(client)
def unregister(self, current_clients):
for client in self.clients:
if client.session == current_clients.session:
self.clients.remove(client)
@property
def total(self):
return self.__total
def add_order(self, customer_session):
if not self.total == 0:
self.__total -= 1
self.notify(customer_session)
def cancel_order(self, customer_session):
if not self.total == 100:
self.__total += 1
self.notify(customer_session)
def notify(self, customer_session):
for client in self.clients:
client.callback(customer_session, self.total)
前端js修改
var goodsClient = new WebSocket('ws://127.0.0.1:8000/websocket_goods');
goodsClient.onopen = function(e) {
var session = $('input[name="session"]'),
data = {
'status': 'register',
'session': session
};
this.send(JSON.stringify(data));
console.log('connected');
}
goodsClient.onmessage = function(e) {
// 接受websocket消息
var data = null,
message = { data: data };
try {
message.data = JSON.parse(evt.data);
} catch (e) {
message.data = evt;
}
$("#total").text(message.data.count);
}