openresty聊天室的helloworld

阅读更多
openresty的websocket + redis的subscribe


参考
https://blog.csdn.net/orangleliu/article/details/50898014
利用redis的subscribe
参考 http://www.runoob.com/redis/pub-sub-subscribe.html

安装redis
brew install redis
安装openresty:
brew install openssl  

  
./configure --prefix=/usr/local/openresty --with-openssl=/usr/local/Cellar/openssl/1.0.2o_1  
make  
make install

openssl还是有问题 shared等
参考
https://blog.csdn.net/csdncqmyg/article/details/73835354

bundle/nginx-x-x-x(版本号)/auto/lib/openssl/conf
把.openssl删掉 ,只删这个单词

nginx调用的lua模块
ws_resdis_json.lua
local server = require "resty.websocket.server"
local redis = require "resty.redis"

local cjson = require "cjson"

--local channel_name = "chat"
local msg_id = 0
local wb, err = server:new{
  timeout = 10000,
  max_payload_len = 65535
}
if not wb then
  ngx.log(ngx.ERR, "failed to new websocket: ", err)
  return ngx.exit(444)
end

function creatChanel(channel_name)
	push = function()
	    -- --create redis
	    local red = redis:new()
	    red:set_timeout(5000) -- 1 sec
	    local ok, err = red:connect("127.0.0.1", 6379)
	    if not ok then
	        ngx.log(ngx.ERR, "failed to connect redis: ", err)
	        wb:send_close()
	        return
	    end

	    --sub
	    local res, err = red:subscribe(channel_name)
	    if not res then
	        ngx.log(ngx.ERR, "failed to sub redis: ", err)
	        wb:send_close()
	        return
	    end

	    -- loop : read from redis
	    while true do
	        local res, err = red:read_reply()
	        if res then
	            local item = res[3]
	            local bytes, err = wb:send_text(tostring(msg_id).." "..item)
	            if not bytes then
	                -- better error handling
	                ngx.log(ngx.ERR, "failed to send text: ", err)
	                return ngx.exit(444)
	            end
	            msg_id = msg_id + 1
	        end
	    end
	end


	co = ngx.thread.spawn(push)
end

--main loop
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 not data then
        local bytes, err = wb:send_ping()
        if not bytes then
          ngx.log(ngx.ERR, "failed to send ping: ", err)
          return ngx.exit(444)
        end
        ngx.log(ngx.ERR, "send ping: ", data)
    elseif typ == "close" then
        break
    elseif typ == "ping" then
        local bytes, err = wb:send_pong()
        if not bytes then
            ngx.log(ngx.ERR, "failed to send pong: ", err)
            return ngx.exit(444)
        end
    elseif typ == "pong" then
        ngx.log(ngx.ERR, "client ponged")
    elseif typ == "text" then
		--local json_str = '{"name": "Bruce.Lin", "age": 25}'
		local json_str = data
   		local json = cjson.decode(json_str)

    	local channel_name = json["name"]
    	creatChanel(channel_name)

        --send to redis
        local red2 = redis:new()
        red2:set_timeout(1000) -- 1 sec
        local ok, err = red2:connect("127.0.0.1", 6379)
        if not ok then
            ngx.log(ngx.ERR, "failed to connect redis: ", err)
            break
        end
        local res, err = red2:publish(channel_name, data)
        if not res then
            ngx.log(ngx.ERR, "failed to publish redis: ", err)
        end
    end
end

wb:send_close()
ngx.thread.wait(co)

nginx的配置文件
加入
	location = /sredis {
    	    content_by_lua_file conf/lua/ws_redis_json.lua;
    	}

客户端代码




    
    
    



	{"name": "Bruce.Lin", "age": 25}
    





测试,进入聊天室
{"name": "Bruce.Lin", "age": 25}

name就是发给聊天室的name

你可能感兴趣的:(redis,nginx,lua,openresty)