python websocket实现消息推送_使用websocket协议完成推送(tornado.websocket.WebSocketHandler)...

关于WebSocket

WebSocket API是下一代客户端-服务器的异步通信方法。该通信取代了单个的TCP套接字,使用ws或wss协议,可用于任意的客户端和服务器程序。WebSocket目前由W3C进行标准化。WebSocket已经受到Firefox 4、Chrome 4、Opera 10.70以及Safari 5等浏览器的支持。

WebSocket API最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。WebSocket并不限于以Ajax(或XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息;XHR受到域的限制,而WebSocket允许跨域通信。

Ajax技术很聪明的一点是没有设计要使用的方式。WebSocket为指定目标创建,用于双向推送消息

精简的说,websocket在任意时刻服务器和客户端之间相互发送信息,而不是传统客服端发送request 服务器来响应

使用这个机制可以达到推送的效果

Tornado对于websocket的实现

使用时继承这个类,比如:

class EchoWebSocket(websocket.WebSocketHandler):

#连接websocket服务器时进行的event

def open(self):

print "WebSocket opened"

#收到信息的时候进行的动作

def on_message(self, message):

#write_message用于主动写信息,这里将收到的信息原样返回

self.write_message(u"You said: " + message)

#关系连接时的动作

def on_close(self):

print "WebSocket closed"

#主动调用close()函数可以关闭这个连接

关于js、android(java)端都与实现websocket的方法,相关资料也容易找到

和上面的例子对应的js是

var ws = new WebSocket("ws://localhost:8888/websocket");

ws.onopen = function() {

ws.send("Hello, world");

};

ws.onmessage = function (evt) {

alert(evt.data);

};

使用websocket聊天

这个例子来自tornado的github

#!/usr/bin/env python

#

# Copyright 2009 Facebook

#

# Licensed under the Apache License, Version 2.0 (the "License"); you may

# not use this file except in compliance with the License. You may obtain

# a copy of the License at

#

# http://www.apache.org/licenses/LICENSE-2.0

#

# Unless required by applicable law or agreed to in writing, software

# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT

# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the

# License for the specific language governing permissions and limitations

# under the License.

"""Simplified chat demo for websockets.

Authentication, error handling, etc are left as an exercise for the reader :)

"""

import logging

import tornado.escape

import tornado.ioloop

import tornado.options

import tornado.web

import tornado.websocket

import os.path

import uuid

from tornado.options import define, options

define("port", default=8888, help="run on the given port", type=int)

class Application(tornado.web.Application):

def __init__(self):

handlers = [

(r"/", MainHandler),

(r"/chatsocket", ChatSocketHandler),

]

settings = dict(

cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",

template_path=os.path.join(os.path.dirname(__file__), "templates"),

static_path=os.path.join(os.path.dirname(__file__), "static"),

xsrf_cookies=True,

)

tornado.web.Application.__init__(self, handlers, **settings)

class MainHandler(tornado.web.RequestHandler):

def get(self):

self.render("index.html", messages=ChatSocketHandler.cache)

class ChatSocketHandler(tornado.websocket.WebSocketHandler):

waiters = set()

cache = []

cache_size = 200

def get_compression_options(self):

# Non-None enables compression with default options.

return {}

def open(self):

ChatSocketHandler.waiters.add(self)

def on_close(self):

ChatSocketHandler.waiters.remove(self)

@classmethod

def update_cache(cls, chat):

cls.cache.append(chat)

if len(cls.cache) > cls.cache_size:

cls.cache = cls.cache[-cls.cache_size:]

@classmethod

def send_updates(cls, chat):

logging.info("sending message to %d waiters", len(cls.waiters))

for waiter in cls.waiters:

try:

waiter.write_message(chat)

except:

logging.error("Error sending message", exc_info=True)

def on_message(self, message):

logging.info("got message %r", message)

parsed = tornado.escape.json_decode(message)

chat = {

"id": str(uuid.uuid4()),

"body": parsed["body"],

}

chat["html"] = tornado.escape.to_basestring(

self.render_string("message.html", message=chat))

ChatSocketHandler.update_cache(chat)

ChatSocketHandler.send_updates(chat)

def main():

tornado.options.parse_command_line()

app = Application()

app.listen(options.port)

tornado.ioloop.IOLoop.instance().start()

if __name__ == "__main__":

main()

我们看ChatSocketHandler这个类:

waiters = set()

cache = []

cache_size = 200

这三个类的成员变量分别维护了在线聊天者"waiters"

聊天内容缓存cache

和最大缓冲值 200

重载了open ()和close()函数分别用于进入聊天室和离开聊天室

def open(self):

ChatSocketHandler.waiters.add(self)

def on_close(self):

ChatSocketHandler.waiters.remove(self)

重载了on_message(self, message)函数用于处理消息进来时的处理

构造了聊天体后用两个类函数进行操作

update_cache将聊天信息进行更新

send_updates对所有在线的人(waiters)进行推送

parsed = tornado.escape.json_decode(message)

chat = {

"id": str(uuid.uuid4()),

"body": parsed["body"],

}

chat["html"] = tornado.escape.to_basestring(

self.render_string("message.html", message=chat))

ChatSocketHandler.update_cache(chat)

ChatSocketHandler.send_updates(chat)

这样服务器端就基本完成了 ,再看下客户端

这里只放上js最基本的文件,有一定jquery基础很容易看懂,这里不做解释

// Copyright 2009 FriendFeed

//

// Licensed under the Apache License, Version 2.0 (the "License"); you may

// not use this file except in compliance with the License. You may obtain

// a copy of the License at

//

// http://www.apache.org/licenses/LICENSE-2.0

//

// Unless required by applicable law or agreed to in writing, software

// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT

// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the

// License for the specific language governing permissions and limitations

// under the License.

$(document).ready(function() {

if (!window.console) window.console = {};

if (!window.console.log) window.console.log = function() {};

$("#messageform").live("submit", function() {

newMessage($(this));

return false;

});

$("#messageform").live("keypress", function(e) {

if (e.keyCode == 13) {

newMessage($(this));

return false;

}

});

$("#message").select();

updater.start();

});

function newMessage(form) {

var message = form.formToDict();

updater.socket.send(JSON.stringify(message));

form.find("input[type=text]").val("").select();

}

jQuery.fn.formToDict = function() {

var fields = this.serializeArray();

var json = {}

for (var i = 0; i < fields.length; i++) {

json[fields[i].name] = fields[i].value;

}

if (json.next) delete json.next;

return json;

};

var updater = {

socket: null,

start: function() {

var url = "ws://" + location.host + "/chatsocket";

updater.socket = new WebSocket(url);

updater.socket.onmessage = function(event) {

updater.showMessage(JSON.parse(event.data));

}

},

showMessage: function(message) {

var existing = $("#m" + message.id);

if (existing.length > 0) return;

var node = $(message.html);

node.hide();

$("#inbox").append(node);

node.slideDown();

}

};

利用websocket实现推送

原理已经很清晰了,可以在android的onmessage函数里增加弹出提示就可以了

使用websocket进行推送有两个缺点

服务器需要维护所有在线设备,开销很大

需要android启动这个进程并保持不断才可以进行推送

### 回答1: 要在Python实现WebSocket消息推送,可以使用第三方库`websocket`。以下是一个简单的示例代码: ```python import websocket import time def on_message(ws, message): print(message) def on_error(ws, error): print(error) def on_close(ws): print("Connection closed") def on_open(ws): def run(*args): for i in range(3): time.sleep(1) ws.send("Hello %d" % i) time.sleep(1) ws.close() print("Thread terminating...") thread.start_new_thread(run, ()) if __name__ == "__main__": websocket.enableTrace(True) ws = websocket.WebSocketApp("ws://localhost:8000/", on_message = on_message, on_error = on_error, on_close = on_close) ws.on_open = on_open ws.run_forever() ``` 在上述代码中,`websocket`库提供了WebSocket的客户端实现。我们定义了四个回调函数`on_message`、`on_error`、`on_close`和`on_open`,分别用于处理接收到的消息、连接错误、连接关闭和连接打开事件。当连接打开时,我们可以在`on_open`回调函数中定义发送消息的逻辑,如发送"Hello"消息。最后,调用`ws.run_forever()`方法使WebSocket客户端一直保持连接,直到连接被关闭。 ### 回答2: Python可以使用的库来实现WebSocket推送消息有很多,其中比较流行的有`websockets`和`Flask-SocketIO`。 使用`websockets`库实现WebSocket推送消息的步骤如下: 1. 安装`websockets`库:在命令行中运行`pip install websockets`。 2. 导入`websockets`库:在Python脚本中使用`import websockets`。 3. 创建WebSocket服务器:使用`websockets`库的`serve`方法创建WebSocket服务器,并指定处理连接和消息的回调函数。 4. 编写回调函数:在回调函数中处理WebSocket连接和接收的消息,并根据需求进行相关处理,如向连接的客户端发送消息。 5. 启动WebSocket服务器:使用`websockets`库的`serve`方法的`serve_forever`方法来启动WebSocket服务器。 使用`Flask-SocketIO`库实现WebSocket推送消息的步骤如下: 1. 安装`Flask-SocketIO`库:在命令行中运行`pip install flask-socketio`。 2. 导入`Flask-SocketIO`库:在Python脚本中使用`from flask_socketio import SocketIO, send`。 3. 创建Flask应用程序:使用Flask库创建一个应用程序对象。 4. 初始化`SocketIO`对象:在应用程序对象中初始化`SocketIO`对象,以便在应用中使用WebSocket功能。 5. 编写事件处理函数:在应用程序中编写处理WebSocket连接和接收消息的事件处理函数,并使用`@socketio.on`装饰器将其与特定的事件关联。 6. 启动应用程序:使用`socketio.run`方法来运行Flask应用程序以启动WebSocket服务器。 以上是两种常用的Python实现WebSocket推送消息的方法,开发者可以根据实际需求选择合适的库和方法进行使用。 ### 回答3: Python可以通过第三方库实现WebSocket推送消息。其中,TornadoWebSocket库是常用的选择。 Tornado库是一个强大的非阻塞Web服务器,它内置了一个可以处理WebSocket的模块。首先,我们需要安装Tornado库,可以使用pip命令进行安装。安装完成后,可以使用下面的代码实现WebSocket推送消息: ```python import tornado.ioloop import tornado.web import tornado.websocket class WebSocketHandler(tornado.websocket.WebSocketHandler): # 存储所有连接的客户端 clients = [] # 当有新的WebSocket连接时调用 def open(self): print("WebSocket opened") self.clients.append(self) # 接收到客户端消息时调用 def on_message(self, message): print("Received message: %s" % message) # 向所有连接的客户端发送消息 for client in self.clients: client.write_message(message) # 当WebSocket连接关闭时调用 def on_close(self): print("WebSocket closed") self.clients.remove(self) app = tornado.web.Application([ (r"/websocket", WebSocketHandler), ]) if __name__ == "__main__": app.listen(8888) tornado.ioloop.IOLoop.instance().start() ``` 以上代码定义了一个WebSocketHandler类,在其中实现WebSocket连接的相关处理逻辑。当有一个新的WebSocket连接时,首先将其存储到clients列表中;当收到客户端的消息时,将消息发送给所有连接的客户端;当WebSocket连接关闭时,从clients列表中移除。 最后,创建一个Tornado应用并监听8888端口,开启事件循环。这样,我们就可以通过访问"ws://localhost:8888/websocket"与WebSocket服务器建立连接,并通过发送消息与其他连接的客户端进行通信。 希望以上内容能帮助到您,如果还有其他问题,请随时追问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值