Skip to content

Commit

Permalink
Fix WebSocket concurrents send (#1197)
Browse files Browse the repository at this point in the history
  • Loading branch information
attdona authored Nov 27, 2024
1 parent 4a0bf01 commit 0854b3e
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 7 deletions.
16 changes: 9 additions & 7 deletions src/WebSockets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -182,22 +182,24 @@ end

# writing a single frame
function writeframe(io::IO, x::Frame)
n = write(io.io, hton(uint16(x.flags)))
buff = IOBuffer()
n = write(buff, hton(uint16(x.flags)))
if x.extendedlen !== nothing
n += write(io.io, hton(x.extendedlen))
n += write(buff, hton(x.extendedlen))
end
if x.mask != EMPTY_MASK
n += write(io.io, UInt32(x.mask))
n += write(buff, UInt32(x.mask))
end
pl = x.payload
# manually unroll a few known type cases to help the compiler
if pl isa Vector{UInt8}
n += write(io.io, pl)
elseif pl isa Base.CodeUnits{UInt8, String}
n += write(io.io, pl)
n += write(buff, pl)
elseif pl isa Base.CodeUnits{UInt8,String}
n += write(buff, pl)
else
n += write(io.io, pl)
n += write(buff, pl)
end
write(io.io, take!(buff))
return n
end

Expand Down
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ isok(r) = r.status == 200
"mwe.jl",
"httpversion.jl",
"websockets/autobahn.jl",
"websockets/multiple_writers.jl",
]
# ARGS can be most easily passed like this:
# import Pkg; Pkg.test("HTTP"; test_args=`ascii.jl parser.jl`)
Expand Down
43 changes: 43 additions & 0 deletions test/websockets/multiple_writers.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Test
using HTTP.WebSockets

function write_message(ws, msg)
send(ws, msg)
end

function client_twin(ws)
for count in 1:10
@async write_message(ws, count)
end
end

function serve(ch)
WebSockets.listen!("127.0.0.1", 8081) do ws
client_twin(ws)
response = receive(ws)
put!(ch, response)
end
end

ch = Channel(1)
srvtask = @async serve(ch)

WebSockets.open("ws://127.0.0.1:8081") do ws
try
while true
s = receive(ws)
if s == "10"
send(ws, "ok")
end
end
catch e
if e.message.status !== 1000
@error "Ws client: $e"
!ws.writeclosed && send(ws, "error")
end
end
end;

@testset "WebSocket multiple writes" begin
@test take!(ch) == "ok"
end

0 comments on commit 0854b3e

Please sign in to comment.