gimite / web-socket-js

HTML5 Web Socket implementation powered by Flash
BSD 3-Clause "New" or "Revised" License
2.73k stars 489 forks source link

Cannot make flash policy work with websocketjs #132

Closed trungnq97 closed 11 years ago

trungnq97 commented 11 years ago

I have setup like this: Flask & gevent-websocket for websocket server, Websocketjs for client side. I tried to disable websocket in Firefox to test flash function. But I cannot make it work. (Everything works fine with native websocket). The policy server actually printed some output like "Client connected, served policy...", but Client side still complained like this:

[WebSocket] cannot connect to Web Socket server at ws://example.com:5000/ (SecurityError: Error #2048: Security sandbox violation: http://example.com:5000/WebSocketMain.swf cannot load data from example.com:5000.)
make sure the server is running and Flash socket policy file is correctly placed

Anybody has some suggestion?

Flask gevent websocket server: run.py

from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer
from flask import Flask, request, render_template

app = Flask(__name__, static_url_path="")

clients = []

@app.route("/")
def api():
    if request.environ.get("wsgi.websocket"):
        ws = request.environ["wsgi.websocket"]
        clients.append(ws)
        while True:
            print ws, " waiting..."
            try:
                message = ws.receive()
                for client in clients:
                    #if client is not ws:
                    client.send(message)
                print len(message)
            except:
                print "ERROR"
                break

        clients.remove(ws)
        print ws, " is out"
        print len(clients)

if __name__ == '__main__':
    http_server = WSGIServer(('', 5000), app, handler_class=WebSocketHandler)
    http_server.serve_forever()

Policy server: policy.py

from gevent.server import StreamServer

policy = """<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy><allow-access-from domain="*" to-ports="*"/></cross-domain-policy>"""

def handle(sock, address):
    s = sock.makefile()
    while True:
        expected = "<policy-file-request/>"
        msg = s.read(len(expected))
        if msg == expected:
            sock.sendall(policy)
            print("Client connected, served policy (%s:%s)" % address)
        else:
            print("Client disconnected (%s:%s)" % address)
            break

if __name__ == "__main__":
    server = StreamServer(('0.0.0.0', 843), handle)
    server.serve_forever()

HTML & JS: index.html

<!doctype html>
<html>
<head>
    <title>Websocket & Audio streaming</title>
</head>
<body>
    <input type="text" name="message" /><button>Send</button>

    <div id="output"></div>

    <script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="swfobject.js"></script>
    <script type="text/javascript" src="web_socket.js"></script>

    <script type="text/javascript">

        // Set URL of your WebSocketMain.swf here:
        WEB_SOCKET_SWF_LOCATION = "WebSocketMain.swf";
        // Set this to dump debug message from Flash to console.log:
        WEB_SOCKET_DEBUG = true;

        window.URL = window.URL || window.webkitURL;

        $(function () {

            window.ws = new WebSocket("ws://" + window.location.host + "/");

            ws.binaryType = "arraybuffer";

            ws.onmessage = function (message) {
                $("#output").append("<p>" + message.data + "</p>");
            }

            $("button").click(function (e) {
                if (ws) {
                    ws.send($("input[name=message]").val());
                }
            });

        });
    </script>

</body>
</html>

--Trung

gimite commented 11 years ago

Maybe you need to close the socket after sending socket policy file content? i.e. after sock.sendall(policy)

trungnq97 commented 11 years ago

Thanks a lot gimite!! It just works now after I close the socket. Thank you for the library also. It's great :-)