SAE上的Channel服务演示

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
简介:

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.channel
import urllib

def 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 re
import tornado.ioloop
import tornado.websocket
import tornado.gen
import tornado.iostream
import tornado.httpclient
import tornado.httputil

@tornado.gen.coroutine
def 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.coroutine
def 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'''
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>zchannel</title>
</head>
<body>

  <iframe name="iframe" style="display: none;"></iframe>
  <form action="http://zchannel.sinaapp.com/" method="post" target="iframe">
    <input type="text" name="msg" /><button type="submit">发送</button>
  </form>
  <pre id="show">
  </pre>

<script type="text/javascript">

var ws = new WebSocket('%s');

ws.onmessage = function(msg){
  document.getElementById('show').innerHTML += '<br /> > ' + msg.data;
}

</script>

</body>
</html>
'''

CHANNEL_NAME = 'zchannel'

import sae.channel
import urllib


def 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://zchannel.sinaapp.com/ 看效果了.


相关实践学习
SAE极速部署弹性微服务商城
本实验带您体验在Serverless应用引擎SAE(Serverless App Engine)上快速部署一个弹性的在线商城微服务应用,使得终端用户可以通过公网访问访问该商城,并进行压力测试以验证其性能与稳定性。
目录
相关文章
|
监控 Serverless 测试技术
Serverless 应用引擎常见问题之做的web服务计费如何解决
Serverless 应用引擎(Serverless Application Engine, SAE)是一种完全托管的应用平台,它允许开发者无需管理服务器即可构建和部署应用。以下是Serverless 应用引擎使用过程中的一些常见问题及其答案的汇总:
491 3
|
运维 Serverless 调度
Serverless 应用引擎常见问题之资源使用完影响服务使用如何解决
Serverless 应用引擎(Serverless Application Engine, SAE)是一种完全托管的应用平台,它允许开发者无需管理服务器即可构建和部署应用。以下是Serverless 应用引擎使用过程中的一些常见问题及其答案的汇总:
|
存储 Devops Serverless
我对SAE这款服务有了一定的了解
我对SAE这款服务有了一定的了解
121 1
|
运维 JavaScript Java
Serverless 应用引擎产品使用之在阿里云函数计算中想为两个不同的服务分别开通自定义域名如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
139 1
|
运维 Serverless API
Serverless 应用引擎使用问题之如何开发HTTP服务
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
Kubernetes 前端开发 Serverless
Serverless 应用引擎产品使用合集之如何调用Kubernetes集群内服务
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
监控 Serverless 应用服务中间件
Serverless 应用引擎操作报错合集之使用自定义镜像部署GPU服务时,报错 "CPU is required but not provided",是什么导致的
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
155 2
|
运维 Serverless API
Serverless 应用引擎产品使用合集之一个函数是否可以作为另一个函数的输入或服务进行调用
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
弹性计算 运维 Serverless
Serverless 应用引擎产品使用之在阿里函数计算中,使用阿里云API或SDK从函数计算调用ECS实例的服务如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
202 4
|
运维 关系型数据库 Serverless
Serverless 应用引擎产品使用合集之如何授权某个函数计算服务给某个RAM子账号访问
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。

热门文章

最新文章