Skip to content

Commit 0854b3e

Browse files
authored
Fix WebSocket concurrents send (#1197)
1 parent 4a0bf01 commit 0854b3e

File tree

3 files changed

+53
-7
lines changed

3 files changed

+53
-7
lines changed

src/WebSockets.jl

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,22 +182,24 @@ end
182182

183183
# writing a single frame
184184
function writeframe(io::IO, x::Frame)
185-
n = write(io.io, hton(uint16(x.flags)))
185+
buff = IOBuffer()
186+
n = write(buff, hton(uint16(x.flags)))
186187
if x.extendedlen !== nothing
187-
n += write(io.io, hton(x.extendedlen))
188+
n += write(buff, hton(x.extendedlen))
188189
end
189190
if x.mask != EMPTY_MASK
190-
n += write(io.io, UInt32(x.mask))
191+
n += write(buff, UInt32(x.mask))
191192
end
192193
pl = x.payload
193194
# manually unroll a few known type cases to help the compiler
194195
if pl isa Vector{UInt8}
195-
n += write(io.io, pl)
196-
elseif pl isa Base.CodeUnits{UInt8, String}
197-
n += write(io.io, pl)
196+
n += write(buff, pl)
197+
elseif pl isa Base.CodeUnits{UInt8,String}
198+
n += write(buff, pl)
198199
else
199-
n += write(io.io, pl)
200+
n += write(buff, pl)
200201
end
202+
write(io.io, take!(buff))
201203
return n
202204
end
203205

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ isok(r) = r.status == 200
3131
"mwe.jl",
3232
"httpversion.jl",
3333
"websockets/autobahn.jl",
34+
"websockets/multiple_writers.jl",
3435
]
3536
# ARGS can be most easily passed like this:
3637
# import Pkg; Pkg.test("HTTP"; test_args=`ascii.jl parser.jl`)

test/websockets/multiple_writers.jl

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using Test
2+
using HTTP.WebSockets
3+
4+
function write_message(ws, msg)
5+
send(ws, msg)
6+
end
7+
8+
function client_twin(ws)
9+
for count in 1:10
10+
@async write_message(ws, count)
11+
end
12+
end
13+
14+
function serve(ch)
15+
WebSockets.listen!("127.0.0.1", 8081) do ws
16+
client_twin(ws)
17+
response = receive(ws)
18+
put!(ch, response)
19+
end
20+
end
21+
22+
ch = Channel(1)
23+
srvtask = @async serve(ch)
24+
25+
WebSockets.open("ws://127.0.0.1:8081") do ws
26+
try
27+
while true
28+
s = receive(ws)
29+
if s == "10"
30+
send(ws, "ok")
31+
end
32+
end
33+
catch e
34+
if e.message.status !== 1000
35+
@error "Ws client: $e"
36+
!ws.writeclosed && send(ws, "error")
37+
end
38+
end
39+
end;
40+
41+
@testset "WebSocket multiple writes" begin
42+
@test take!(ch) == "ok"
43+
end

0 commit comments

Comments
 (0)