使用 OpenResty 架设 Websocket Echo Server

喜大普奔! 春哥维护的 OpenResty 项目今天发布了 1.4.2.9 版本,最大的改进就是集成了 LuaRestyWebSocketLibrary ,这让开发 Websocket 服务器变得非常简单,这里我记录一下做一个简单的 echo server 。

我使用的系统是 ubuntu 13.04 64位,使用的 websocket 客户端是由 Python 编写的 websocket-client ( https://github.com/liris/websocket-client )。

首先下载 OpenResty 源代码、编译:

wget http://openresty.org/download/ngx_openresty-1.4.2.9.tar.gz

tar zxvf ngx_openresty-1.4.2.9.tar.gz

cd ngx_openresty-1.4.2.9

./configure --with-luajit

注意, OpenResty 依赖 perl 5.6.1+, libreadline, libpcre, libssl ,因为我已经安装过了,所这里没有安装步骤。如果没有安装可以执行 sudo apt-get install libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl make 进行安装。

$ make
$ sudo make install

这样 OpenResty 就被安装到默认的 /usr/local/openresty 目录中了,我们验证一下。

$ cd /usr/local/openresty/nginx/sbin
$ ./nginx -V
nginx version: ngx_openresty/1.4.2.9
built by gcc 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1)
TLS SNI support enabled
configure arguments: --prefix=/usr/local/openresty/nginx --add-module=../ngx_devel_kit-0.2.19 --add-module=../echo-nginx-module-0.48 --add-module=../xss-nginx-module-0.03rc9 --add-module=../ngx_coolkit-0.2rc1 --add-module=../set-misc-nginx-module-0.22 --add-module=../form-input-nginx-module-0.07 --add-module=../encrypted-session-nginx-module-0.03 --add-module=../srcache-nginx-module-0.22 --add-module=../ngx_lua-0.9.0 --add-module=../headers-more-nginx-module-0.22 --add-module=../array-var-nginx-module-0.03rc1 --add-module=../memc-nginx-module-0.13 --add-module=../redis2-nginx-module-0.10 --add-module=../redis-nginx-module-0.3.6 --add-module=../auth-request-nginx-module-0.2 --add-module=../rds-json-nginx-module-0.12rc10 --add-module=../rds-csv-nginx-module-0.05rc2 --with-ld-opt=-Wl,-rpath,/usr/local/openresty/luajit/lib --with-http_ssl_module

然后我们编写一个需要使用的 nginx 配置文件:

#file: ~/Works/OpenResty/echo/nginx.conf

worker_processes  1;

events {
    worker_connections 1024;
}

http {
    server {
        listen 80;

        location /s {
            content_by_lua '

            local server = require "resty.websocket.server"

            local wb, err = server:new{
              timeout = 5000,
              max_payload_len = 65535
            }

            if not wb then
              ngx.log(ngx.ERR, "failed to new websocket: ", err)
              return ngx.exit(444)
            end

            while true do
              local data, typ, err = wb:recv_frame()

              if wb.fatal then
                ngx.log(ngx.ERR, "failed to receive frame: ", err)
                return ngx.exit(444)
              end

              if typ == "close" then break

              elseif typ == "text" then
                local bytes, err = wb:send_text(data)
                if not bytes then
                  ngx.log(ngx.ERR, "failed to send text: ", err)
                  return ngx.exit(444)
                end
              end

            end
            wb:send_close()

            ';
        }
    }
}

然后启动加载写好的配置启动 OpenResty :

$ sudo /usr/local/openresty/nginx/sbin/nginx  -c ~/Works/OpenResty/echo/nginx.conf

然后我们用 Python 写个 client 测试一下:

#file: test_echo.py

from websocket import create_connection
ws = create_connection("ws://localhost/s")

print "Sending 'test echo'..."
ws.send("test echo")
print "Sent"
print "Reeiving..."
result =  ws.recv()
print "Received '%s'" % result
ws.close()

执行脚本

$ python test_echo.py
Sending 'test echo'...
Sent
Reeiving...
Received 'test echo'

测试成功!

这样,一个高性能的 websocket echo server 就搭建好了。

Python 2.7 标准库:内置函数

Python 语言哲学我们可以简单的概括为:简单。

为了实现“简单”这个目标, Python 在语言本身就内置包含了很多已有的函数和类库,我们称之为标准库。

所以,对于 Python 而言,语言本身固然重要,而熟悉 Python 的标准库,却更符合 Python 的精神,一切简单为准,有现成的就不要自己去实现。

熟悉 Python 标准库也就成了学习 Python 的一个重要内容。

先复习一下常用的内置函数。

Read More …

Haskell 简易入门教程

Haskell 是面向实用而设计的纯函数式编程语言。 Haskell 以其单子系统与类型系统著称,不过我在这里介绍 Haskell 更是因为它的优雅。对我而言,使用 Haskell 写代码是一个非常愉快的过程。

在 Ubuntu 中安装 Haskell 环境非常简单: sudo apt-get install ghc ,然后键入 ghci 就进入了交互式命令行界面。

Read More …