Comments (8)
@wuyachao BTW, you have the following line in your websocket server code:
wb:set_timeout(1000) -- change the network timeout to 1 second
It starts with 5 sec timeout but you change it to 1 sec inside the loop.
from lua-resty-websocket.
@wuyachao Your example is not standalone, we do not even know how you initialize your wb
object. I suggest you provide a standalone and minimal example that can easily run on others' machines and reproduce the problem.
It seems that neither operation now in progress
nor the protocol wrong type for socket
are error messages produced by OpenResty. Maybe there's a problem on your other side of the websocket wire?
from lua-resty-websocket.
@agentzh thanks for your reply. this is my demo.
local client = require "resty.websocket.client"
local wb, err = client:new()
local uri = "ws://127.0.0.1:3000/ws"
local ok, err = wb:connect(uri)
if not ok then
ngx.say("failed to connect: " .. err)
return
end
local i = 0
while true do
ngx.say(i)
local bytes, err = wb:send_text("ping mmm")
ngx.say("send msg:", bytes)
if not bytes then
ngx.say("failed to send frame: ", err)
return
end
local bytes, err = wb:send_ping()
ngx.say("send ping:", bytes)
if not bytes then
ngx.say("failed to send frame: ", err)
return
end
local bytes, err = wb:send_pong()
ngx.say("send pong:", bytes)
if not bytes then
ngx.say("failed to send frame: ", err)
return
end
local data, typ, err = wb:recv_frame()
if not data then
ngx.say("failed to receive the frame: ", err)
return
end
ngx.say("received: ", data, " (", typ, "): ", err)
i = i + 1
ngx.sleep(2)
end
local bytes, err = wb:send_close()
if not bytes then
ngx.say("failed to send frame: ", err)
return
end
ngx.say("end")
the other side of websocket is https://gist.github.com/wuyachao/ea16adc974a53a51ea8fa98fb89ec2ac
from lua-resty-websocket.
@wuyachao Can you make the server openresty as well? We do not want to debug issues in a Go server. That's not our concern.
from lua-resty-websocket.
@agentzh sorry. this is the code of server side. listen on port :8850
local server = require "resty.websocket.server"
local wb, err = server:new{
timeout = 5000, -- in milliseconds
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 not data then
ngx.log(ngx.ERR, "failed to receive a frame: ", err)
return ngx.exit(444)
end
if typ == "close" then
-- for typ "close", err contains the status code
local code = err
-- send a close frame back:
local bytes, err = wb:send_close(1000, "enough, enough!")
if not bytes then
ngx.log(ngx.ERR, "failed to send the close frame: ", err)
return
end
ngx.log(ngx.INFO, "closing with status code ", code, " and message ", data)
return
end
if typ == "ping" then
-- send a pong frame back:
local bytes, err = wb:send_pong(data)
if not bytes then
ngx.log(ngx.ERR, "failed to send frame: ", err)
return
end
elseif typ == "pong" then
-- just discard the incoming pong frame
else
ngx.log(ngx.INFO, "received a frame of type ", typ, " and payload ", data)
end
wb:set_timeout(1000) -- change the network timeout to 1 second
local bytes, err = wb:send_text("Hello world")
if not bytes then
ngx.log(ngx.ERR, "failed to send a text frame: ", err)
return ngx.exit(444)
end
end
local bytes, err = wb:send_close(1000, "enough, enough!")
if not bytes then
ngx.log(ngx.ERR, "failed to send the close frame: ", err)
return
end
the client request it per second.
local client = require "resty.websocket.client"
--ngx.say(1111111)
--ngx.exit(200)
--while true do
-- ngx.say(111)
-- ngx.sleep(2000)
--end
local wb, err = client:new()
--local uri = "ws://127.0.0.1:3000/websocket"
local uri = "ws://127.0.0.1:8850"
local ok, err = wb:connect(uri)
if not ok then
ngx.say("failed to connect: " .. err)
return
end
local i = 0
while true do
ngx.say(i)
local bytes, err = wb:send_text("ping mmm")
ngx.say("send msg:", bytes)
if not bytes then
ngx.say("failed to send frame: ", err)
return
end
local bytes, err = wb:send_ping()
ngx.say("send ping:", bytes)
if not bytes then
ngx.say("failed to send frame: ", err)
return
end
-- ngx.say(i)
-- ngx.sleep(2000)
local bytes, err = wb:send_pong()
ngx.say("send pong:", bytes)
if not bytes then
ngx.say("failed to send frame: ", err)
return
end
local data, typ, err = wb:recv_frame()
if not data then
ngx.say("failed to receive the frame: ", err)
return
end
ngx.say("received: ", data, " (", typ, "): ", err)
i = i + 1
ngx.sleep(1)
end
local bytes, err = wb:send_close()
if not bytes then
ngx.say("failed to send frame: ", err)
return
end
curl localhost:8888:
0
send msg:14
send ping:6
send pong:6
received: Hello world (text): nil
1
send msg:14
send ping:6
send pong:6
received: (pong): nil
2
send msg:nil
failed to send frame: failed to send frame: operation now in progress
the server error message:
2017/12/13 11:25:12 [error] 31460#0: *5 lua tcp socket read timed out, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "127.0.0.1:8850"
2017/12/13 11:25:12 [error] 31460#0: *5 [lua] main.lua:16: failed to receive a frame: failed to receive the first 2 bytes: timeout, client: 127.0.0.1, server: , request: "GET / HTTP/1.1", host: "127.0.0.1:8850"
but the websocket server timeout is 5 second. I request it per second.
from lua-resty-websocket.
@wuyachao Well, the problem is that your websocket server should handle reading timeout errors gracefully instead of terminating the connection with ngx.exit(444)
. I can see that the code example in README is oversimplified here and it seems that you simply copy the code right over.
Basically you client sends the data every 2 seconds while your server sets the timeout threshold to 1 second, which will surely lead to the (nonfatal) reading timeout errors on your server side.
Another thing is that you need to call ngx.flush(true)
on your client side so that you can see the output sooner.
I've updated your code example accordingly and it works fine on my side:
location /ws {
content_by_lua_block {
local server = require "resty.websocket.server"
local wb, err = server:new{
timeout = 5000, -- in milliseconds
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 not data then
if not string.find(err, "timeout", 1, true) then
ngx.log(ngx.ERR, "failed to receive a frame: ", err)
return ngx.exit(444)
end
end
if typ == "close" then
-- for typ "close", err contains the status code
local code = err
-- send a close frame back:
local bytes, err = wb:send_close(1000, "enough, enough!")
if not bytes then
ngx.log(ngx.ERR, "failed to send the close frame: ", err)
return
end
ngx.log(ngx.INFO, "closing with status code ", code, " and message ", data)
return
end
if typ == "ping" then
-- send a pong frame back:
local bytes, err = wb:send_pong(data)
if not bytes then
ngx.log(ngx.ERR, "failed to send frame: ", err)
return
end
elseif typ == "pong" then
-- just discard the incoming pong frame
else
ngx.log(ngx.INFO, "server received a frame of type ", typ, " and payload ", data)
end
-- wb:set_timeout(1000) -- change the network timeout to 1 second
local bytes, err = wb:send_text("Hello world")
if not bytes then
ngx.log(ngx.ERR, "failed to send a text frame: ", err)
return ngx.exit(444)
end
end
local bytes, err = wb:send_close(1000, "enough, enough!")
if not bytes then
ngx.log(ngx.ERR, "failed to send the close frame: ", err)
return
end
}
}
location /client {
content_by_lua_block {
local client = require "resty.websocket.client"
local wb, err = client:new()
local uri = "ws://127.0.0.1:" .. ngx.var.server_port .. "/ws"
local ok, err = wb:connect(uri)
if not ok then
ngx.say("failed to connect: " .. err)
return
end
local i = 0
while true do
ngx.say(i)
local bytes, err = wb:send_text("ping mmm")
ngx.say("send msg:", bytes)
if not bytes then
ngx.say("failed to send frame: ", err)
return
end
local bytes, err = wb:send_ping()
ngx.say("send ping:", bytes)
if not bytes then
ngx.say("failed to send frame: ", err)
return
end
local bytes, err = wb:send_pong()
ngx.say("send pong:", bytes)
if not bytes then
ngx.say("failed to send frame: ", err)
return
end
local data, typ, err = wb:recv_frame()
if not data then
ngx.say("failed to receive the frame: ", err)
return
end
ngx.say("received: ", data, " (", typ, "): ", err)
i = i + 1
ngx.sleep(2)
ngx.flush(true)
end
local bytes, err = wb:send_close()
if not bytes then
ngx.say("failed to send frame: ", err)
return
end
ngx.say("end")
}
}
And curl works:
$ curl localhost:1984/client
0
send msg:14
send ping:6
send pong:6
received: Hello world (text): nil
1
send msg:14
send ping:6
send pong:6
received: (pong): nil
2
send msg:14
send ping:6
send pong:6
received: Hello world (text): nil
3
send msg:14
send ping:6
send pong:6
received: Hello world (text): nil
4
send msg:14
send ping:6
send pong:6
received: Hello world (text): nil
5
send msg:14
send ping:6
send pong:6
received: (pong): nil
6
...
It emits a few lines of output evey 2 seconds and it will just go on and on forever since you use an infinite loop in both the client side and the server side.
from lua-resty-websocket.
@wuyachao I've updated the code example in the README doc.
from lua-resty-websocket.
@agentzh thank you very much!
from lua-resty-websocket.
Related Issues (20)
- [alert] 3422#0: worker process 4444 exited on signal 11 (core dumped)? HOT 3
- Errors in use with lua-resty-http HOT 2
- bad RSV1, RSV2, or RSV3 bits HOT 1
- Tests are failing on ppc64le
- unexpected connection behavior
- Compilation errors while running sample programs https://github.com/openresty/lua-resty-websocket HOT 4
- RFC 8441 support: WebSockets over h2, h2c
- Run Autobahn Testsuite
- maybe it is websocket client issue or wrong way to use HOT 1
- webscoekt建立连接后收到后端返回的数据帧被截断,只有32k HOT 1
- lj_str_new
- how to access websocket clients / handles from websocket server?
- can not use resty redis HOT 1
- use websocket client to sync data in local redis before nginx is accessible HOT 5
- "send_text" got no error meesage after browser closed HOT 1
- [idea] support HTTP connection reuse HOT 4
- bad RSV1, RSV2, or RSV3 bits
- ssl session repeated sslhandshake HOT 2
- websocket ratelimiting
- How to run perl tests without Test.pm file?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lua-resty-websocket.