博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SAE上的Channel服务演示
阅读量:7223 次
发布时间:2019-06-29

本文共 4039 字,大约阅读时间需要 13 分钟。

1. Channel服务是什么

SAE 上的 Channel 服务就是一个共用的 WebSocket 服务器.

和自建的服务器的双工形式有些不同, 因为是共用的, 所以逻辑必须统一. 于是对于所有往服务器的 操作, 全部是回调对应的应用的固定 URL . 既然这样, 我们就当它不能写好了, 写的相关逻辑, 我们自己在应用上通过 HTTP 实现.

这样, 其实 Channel 服务就是一个很单纯的 广播站 了. 通过 API 写入的数据, 会广播给当前的所有连接.

信息流上, 就是一个简单的环状:

+-----------------+      |   app server    |<----+      +-----------------+     |               |              |               |              |               v              |      +-----------------+     |      | channel server  |     |      +-----------------+     |               |              |               |              |               v              |      +-----------------+     |      | browser/client  |-----+      +-----------------+

当然, 如果你要处理"连接创建", "连接关闭"这两个事件, 那你还是得去处理 Channel 的回调. 只是处理数据的话, 就别管回调了, 上面那个环就可以了.

2. Web服务器

Web服务器, 就是前面环图中的 app server , 它要做两个事:

  • 创建 ws 服务, 即获取一个 ws 服务的 URL .
  • 获取请求数据, 往 channel server 中写入数据.

这两个事对应 sae.channel 中的仅有的两个函数:

  • sae.channel.create_channel(name, duration=None)
  • sae.channel.send_message(name, message)

我们也正好把 GET 方法用于第一件事, 把 POST 方法用于第二件事, index.wsgi 文件:

# -*- coding: utf-8 -*-CHANNEL_NAME = 'zchannel'import sae.channelimport urllibdef application(environ, start_response):    if environ.get('REQUEST_METHOD', 'GET') == 'GET':        #url -> ws://channel.sinaapp.com/com/xxx        url = sae.channel.create_channel(CHANNEL_NAME)        start_response('200 ok', [('content-type', 'text/plain')])        return [url]    length = environ.get('CONTENT_LENGTH', 0)    length = int(length)    body = environ['wsgi.input'].read(length)    msg = urllib.unquote(body.split('=', 1)[1])    sae.channel.send_message(CHANNEL_NAME, msg)    start_response('200 ok', [('content-type', 'text/html')])    return ['ok']

3. 浏览器客户端

高级浏览器对 WebSocket 早已支持, 使用 js 操作 WebSocket 很容易:

var ws = new WebSocket(ws_url);ws.onmessage = function(msg){  console.log(msg)}

当然, 我们可以加一些简单的标签来实现一个页面应用. 后面会有代码.

4. 命令行客户端

Tornado 中已经实现了一个 WebSocket 的客户端(至少 4.0.1 这个版本有), 所以我们可以做一个:

  • 从标准输入中读取内容.
  • 然后以 POST 方法写到 HTTP 服务器.
  • 同时读取 WebSocket 服务器的内容并显示到标准输出.

命令行客户端代码:

# -*- coding: utf-8 -*-import reimport tornado.ioloopimport tornado.websocketimport tornado.genimport tornado.iostreamimport tornado.httpclientimport tornado.httputil@tornado.gen.coroutinedef show_message():    client = tornado.httpclient.AsyncHTTPClient()    res = yield client.fetch('http://zchannel.sinaapp.com/')    ws = re.findall("WebSocket\('(.*?)'\)", res.body)[0];    conn = yield tornado.websocket.websocket_connect(ws)    while 1:        msg = yield conn.read_message()        print '>', msg@tornado.gen.coroutinedef write_message():    stream = tornado.iostream.PipeIOStream(fd=0)    client = tornado.httpclient.AsyncHTTPClient()    while 1:        s = (yield stream.read_until('\n')).rstrip()        yield client.fetch('http://zchannel.sinaapp.com/', method='POST',                           body=tornado.httputil.urlencode({
'msg': s}))if __name__ == '__main__': show_message() write_message() tornado.ioloop.IOLoop.current().start()

直接执行上面的代码, 就可以在终端中输入内容, 并看到 WebSocket 服务器吐出来的数据了.

代码中对 GET 方法访问 HTTP 服务器时获取的数据做了处理, 是因为 GET 方法我不光返回一个简单的 WebSocket 的 URL 了, 而是返回了一个完整的 HTML 页面, WebSocket 的 URL 需要从页面内容中提取. 完整代码在后面.

5. Web服务器改进

Web服务器在实现上, 它的 GET 方法只返回一个 WebSocket 的 URL 有些浪费, 我们可以直接返回一个完整的 HTML 页面, index.wsgi 文件:

# -*- coding: utf-8 -*-s = u'''
zchannel
  
'''CHANNEL_NAME = 'zchannel'import sae.channelimport urllibdef application(environ, start_response): if environ.get('REQUEST_METHOD', 'GET') == 'GET': #url -> ws://channel.sinaapp.com/com/xxx url = sae.channel.create_channel(CHANNEL_NAME) html = (s % url).encode('utf-8') start_response('200 ok', [('content-type', 'text/html')]) return [html] length = environ.get('CONTENT_LENGTH', 0) length = int(length) body = environ['wsgi.input'].read(length) msg = urllib.unquote(body.split('=', 1)[1]) sae.channel.send_message(CHANNEL_NAME, msg) start_response('200 ok', [('content-type', 'text/html')]) return ['ok']

现在可以访问  看效果了.

转载地址:http://fieym.baihongyu.com/

你可能感兴趣的文章
20155222卢梓杰 实验三 免杀原理与实践
查看>>
xubuntu14.04截图,彻底到Linux一个半月后记
查看>>
VS2008(C#)子页嵌套母版页的控件访问方法(三)——嵌套三层母版页的子页
查看>>
python2读取EXCEL表格内的数据时碰到的问题
查看>>
FFmpeg-20160506-snapshot-bin
查看>>
《Ext JS 4.2 实战》可以买了
查看>>
【maven】 在 MyEcplise上使用maven搭建Web项目
查看>>
在html中显示Flash的代码
查看>>
C/C++STL常用容器用法总结
查看>>
gdal库集成MrSID库的做法
查看>>
missing ';' before 'namesapce'错误的解决
查看>>
js 浏览器滑动页面滚动条时,获取元素距离浏览器顶部距离,并且固定浮动导航...
查看>>
iphone Three20如何添加到工程,以及如何添加删除图片的按钮。
查看>>
内核堆分配函数brk()源码分析
查看>>
gops —— Go 程序诊断分析工具
查看>>
PHP json_decode返回null解析失败原因
查看>>
SpringMVC与Struts2的对比
查看>>
Java_eclipse软件与git配合使用创建git仓库
查看>>
极路由饥饿营销引质疑 联合创始人拿数据正面回应
查看>>
配置visual studio code for Mac 调试c/c++
查看>>