add a python websocket proxy which works on Linux, while ws proxy_server does not

This commit is contained in:
Benjamin Sergeant 2019-11-18 13:46:11 -08:00
parent 901c21e499
commit cc492bf1a3
10 changed files with 131 additions and 39 deletions

View File

@ -1 +1 @@
7.3.2 7.3.3

View File

@ -19,6 +19,7 @@ RUN [ "make", "ws_install" ]
FROM alpine as runtime FROM alpine as runtime
RUN apk add --no-cache libstdc++ RUN apk add --no-cache libstdc++
RUN apk add --no-cache strace
RUN addgroup -S app && adduser -S -G app app RUN addgroup -S app && adduser -S -G app app
COPY --chown=app:app --from=build /usr/local/bin/ws /usr/local/bin/ws COPY --chown=app:app --from=build /usr/local/bin/ws /usr/local/bin/ws

View File

@ -1,43 +1,59 @@
version: "3" version: "3"
services: services:
snake: # snake:
image: bsergean/ws:build # image: bsergean/ws:build
entrypoint: ws snake --port 8765 --host 0.0.0.0 --redis_hosts redis1 # entrypoint: ws snake --port 8767 --host 0.0.0.0 --redis_hosts redis1
# ports:
# - "8767:8767"
# networks:
# - ws-net
# depends_on:
# - redis1
# proxy:
# image: bsergean/ws:build
# entrypoint: strace ws proxy_server --remote_host 'wss://cobra.addsrv.com' --host 0.0.0.0 --port 8765 -v
# ports:
# - "8765:8765"
# networks:
# - ws-net
pyproxy:
image: bsergean/ws_proxy:build
entrypoint: /usr/bin/ws_proxy.py --remote_url 'wss://cobra.addsrv.com' --host 0.0.0.0 --port 8765
ports: ports:
- "8765:8765" - "8765:8765"
networks: networks:
- ws-net - ws-net
depends_on:
- redis1
ws: # ws:
security_opt: # security_opt:
- seccomp:unconfined # - seccomp:unconfined
cap_add: # cap_add:
- SYS_PTRACE # - SYS_PTRACE
stdin_open: true # stdin_open: true
tty: true # tty: true
image: bsergean/ws:build # image: bsergean/ws:build
entrypoint: bash # entrypoint: sh
networks: # networks:
- ws-net # - ws-net
depends_on: # depends_on:
- redis1 # - redis1
#
redis1: # redis1:
image: redis:alpine # image: redis:alpine
networks: # networks:
- ws-net # - ws-net
#
statsd: # statsd:
image: jaconel/statsd # image: jaconel/statsd
ports: # ports:
- "8125:8125" # - "8125:8125"
environment: # environment:
- STATSD_DUMP_MSG=true # - STATSD_DUMP_MSG=true
- GRAPHITE_HOST=127.0.0.1 # - GRAPHITE_HOST=127.0.0.1
networks: # networks:
- ws-net # - ws-net
networks: networks:
ws-net: ws-net:

View File

@ -6,4 +6,4 @@
#pragma once #pragma once
#define IX_WEBSOCKET_VERSION "7.3.1" #define IX_WEBSOCKET_VERSION "7.3.3"

View File

@ -57,6 +57,7 @@ docker:
docker_push: docker_push:
docker tag ${IMG} ${LATEST} docker tag ${IMG} ${LATEST}
docker push ${LATEST} docker push ${LATEST}
docker push ${IMG}
run: run:
docker run --cap-add sys_ptrace --entrypoint=sh -it bsergean/ws:build docker run --cap-add sys_ptrace --entrypoint=sh -it bsergean/ws:build

View File

@ -0,0 +1 @@
0.0.1

View File

@ -0,0 +1,8 @@
FROM python:3.8.0-alpine3.10
RUN pip install websockets
COPY ws_proxy.py /usr/bin
RUN chmod +x /usr/bin/ws_proxy.py
EXPOSE 8765
CMD ["python", "/usr/bin/ws_proxy.py"]

View File

@ -0,0 +1,20 @@
.PHONY: docker
NAME := bsergean/ws_proxy
TAG := $(shell cat DOCKER_VERSION)
IMG := ${NAME}:${TAG}
LATEST := ${NAME}:latest
BUILD := ${NAME}:build
docker_test:
docker build -t ${BUILD} .
docker:
git clean -dfx
docker build -t ${IMG} .
docker tag ${IMG} ${BUILD}
docker_push:
docker tag ${IMG} ${LATEST}
docker push ${LATEST}
docker push ${IMG}

View File

@ -0,0 +1,43 @@
#!/usr/bin/env python3
# WS server example
import argparse
import asyncio
import websockets
async def hello(websocket, path):
url = REMOTE_URL + path
async with websockets.connect(url) as ws:
taskA = asyncio.create_task(clientToServer(ws, websocket))
taskB = asyncio.create_task(serverToClient(ws, websocket))
await taskA
await taskB
async def clientToServer(ws, websocket):
async for message in ws:
await websocket.send(message)
async def serverToClient(ws, websocket):
async for message in websocket:
await ws.send(message)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='websocket proxy.')
parser.add_argument('--host', help='Host to bind to.', default='localhost')
parser.add_argument('--port', help='Port to bind to.', default=8765)
parser.add_argument('--remote_url', help='Remote websocket url', default='ws://localhost:8767')
args = parser.parse_args()
REMOTE_URL = args.remote_url
start_server = websockets.serve(hello, args.host, args.port)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

View File

@ -65,14 +65,13 @@ namespace ix
if (msg->type == ix::WebSocketMessageType::Open) if (msg->type == ix::WebSocketMessageType::Open)
{ {
std::cerr << "New connection" << std::endl; std::cerr << "New connection" << std::endl;
std::cerr << "id: " << state->getId() << std::endl; std::cerr << "server id: " << state->getId() << std::endl;
std::cerr << "Uri: " << msg->openInfo.uri << std::endl; std::cerr << "Uri: " << msg->openInfo.uri << std::endl;
std::cerr << "Headers:" << std::endl; std::cerr << "Headers:" << std::endl;
for (auto it : msg->openInfo.headers) for (auto it : msg->openInfo.headers)
{ {
std::cerr << it.first << ": " << it.second << std::endl; std::cerr << it.first << ": " << it.second << std::endl;
} }
state->setConnected();
} }
else if (msg->type == ix::WebSocketMessageType::Close) else if (msg->type == ix::WebSocketMessageType::Close)
{ {
@ -80,6 +79,7 @@ namespace ix
<< " code " << msg->closeInfo.code << " reason " << " code " << msg->closeInfo.code << " reason "
<< msg->closeInfo.reason << std::endl; << msg->closeInfo.reason << std::endl;
webSocket->close(msg->closeInfo.code, msg->closeInfo.reason); webSocket->close(msg->closeInfo.code, msg->closeInfo.reason);
state->setTerminated();
} }
else if (msg->type == ix::WebSocketMessageType::Error) else if (msg->type == ix::WebSocketMessageType::Error)
{ {
@ -108,7 +108,7 @@ namespace ix
if (msg->type == ix::WebSocketMessageType::Open) if (msg->type == ix::WebSocketMessageType::Open)
{ {
std::cerr << "New connection" << std::endl; std::cerr << "New connection" << std::endl;
std::cerr << "id: " << state->getId() << std::endl; std::cerr << "client id: " << state->getId() << std::endl;
std::cerr << "Uri: " << msg->openInfo.uri << std::endl; std::cerr << "Uri: " << msg->openInfo.uri << std::endl;
std::cerr << "Headers:" << std::endl; std::cerr << "Headers:" << std::endl;
for (auto it : msg->openInfo.headers) for (auto it : msg->openInfo.headers)
@ -124,10 +124,12 @@ namespace ix
// we should sleep here for a bit until we've established the // we should sleep here for a bit until we've established the
// connection with the remote server // connection with the remote server
while (!state->isConnected()) while (state->webSocket().getReadyState() != ReadyState::Open)
{ {
std::cerr << "waiting for server connection establishment" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
} }
std::cerr << "server connection established" << std::endl;
} }
else if (msg->type == ix::WebSocketMessageType::Close) else if (msg->type == ix::WebSocketMessageType::Close)
{ {