diff --git a/qtwebsockets.pro b/qtwebsockets.pro
index 58c33f27cacc16d2f4baed83ef3264e8868eb181..0dcd45b820ac1fa3c3735294a8423237e6080396 100644
--- a/qtwebsockets.pro
+++ b/qtwebsockets.pro
@@ -1 +1,2 @@
+requires(qtHaveModule(network))
 load(qt_parts)
diff --git a/src/imports/qmlwebsockets/dependencies.json b/src/imports/qmlwebsockets/dependencies.json
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f101c7a37a4c875e6999bee1a287fdb733380
--- /dev/null
+++ b/src/imports/qmlwebsockets/dependencies.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/src/imports/qmlwebsockets/plugins.qmltypes b/src/imports/qmlwebsockets/plugins.qmltypes
index cbbb628269d91d320139eea6accf3ff4cd19a7f5..2fb57cddecb28bd784aa6088cde10766893bfb86 100644
--- a/src/imports/qmlwebsockets/plugins.qmltypes
+++ b/src/imports/qmlwebsockets/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
 // It is used for QML tooling purposes only.
 //
 // This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtWebSockets 1.1'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json QtWebSockets 1.1'
 
 Module {
     dependencies: []
diff --git a/src/imports/qmlwebsockets/qmlwebsockets.pro b/src/imports/qmlwebsockets/qmlwebsockets.pro
index fa631bda2e7645b2527329272e24eff16e427f3a..7b6fc860da69155fdb9d0facdad94571649e5cfe 100644
--- a/src/imports/qmlwebsockets/qmlwebsockets.pro
+++ b/src/imports/qmlwebsockets/qmlwebsockets.pro
@@ -12,6 +12,6 @@ SOURCES +=  qmlwebsockets_plugin.cpp \
 
 OTHER_FILES += qmldir
 
-IMPORT_VERSION = 1.0
+IMPORT_VERSION = 1.1
 
 load(qml_plugin)
diff --git a/src/websockets/qwebsocket_p.h b/src/websockets/qwebsocket_p.h
index 73f27458d446a477d87a028575e8c3659d93c4aa..fd631d4c433f7269ef034feba8fa43407d76f018 100644
--- a/src/websockets/qwebsocket_p.h
+++ b/src/websockets/qwebsocket_p.h
@@ -69,6 +69,10 @@
 #include "qwebsocketdataprocessor_p.h"
 #include "qdefaultmaskgenerator_p.h"
 
+#ifdef Q_OS_WASM
+#include <emscripten/val.h>
+#endif
+
 QT_BEGIN_NAMESPACE
 
 class QWebSocketHandshakeRequest;
@@ -247,6 +251,9 @@ private:
     QMap<QString, QString> m_headers;
 
     friend class QWebSocketServerPrivate;
+#ifdef Q_OS_WASM
+    emscripten::val socketContext = emscripten::val::null();
+#endif
 };
 
 QT_END_NAMESPACE
diff --git a/src/websockets/qwebsocket_wasm_p.cpp b/src/websockets/qwebsocket_wasm_p.cpp
index 7b9f2716a2e9a50230eaf25d28b67d8f626c667f..2ac61baf631c7cd0096266eb85a6b6eba66b7e46 100644
--- a/src/websockets/qwebsocket_wasm_p.cpp
+++ b/src/websockets/qwebsocket_wasm_p.cpp
@@ -42,92 +42,104 @@
 #include <QtCore/qcoreapplication.h>
 
 #include <emscripten.h>
-#include <emscripten/html5.h>
 #include <emscripten/bind.h>
 
 using namespace emscripten;
 
-QByteArray g_messageArray;
-// easiest way to transliterate binary data to js/wasm
-
-val getBinaryMessage()
+static void q_onErrorCallback(val event)
 {
-    return val(typed_memory_view(g_messageArray.size(),
-                                 reinterpret_cast<const unsigned char *>(g_messageArray.constData())));
-}
+    val target = event["target"];
 
-EMSCRIPTEN_BINDINGS(wasm_module) {
-    function("getBinaryMessage", &getBinaryMessage);
+    QWebSocketPrivate *wsp = reinterpret_cast<QWebSocketPrivate*>(target["data-context"].as<quintptr>());
+    Q_ASSERT (wsp);
+
+    emit wsp->q_func()->error(wsp->error());
 }
 
-static void onOpenCallback(void *data)
+static void q_onCloseCallback(val event)
 {
-    auto handler = reinterpret_cast<QWebSocketPrivate *>(data);
-    Q_ASSERT (handler);
-    emit handler->q_func()->connected();
+    val target = event["target"];
+
+    QWebSocketPrivate *wsp = reinterpret_cast<QWebSocketPrivate*>(target["data-context"].as<quintptr>());
+    Q_ASSERT (wsp);
+
+    emit wsp->q_func()->disconnected();
 }
 
-static void onCloseCallback(void *data, int message)
+static void q_onOpenCallback(val event)
 {
-    Q_UNUSED(message);
-    auto handler = reinterpret_cast<QWebSocketPrivate *>(data);
-    Q_ASSERT (handler);
-    emit handler->q_func()->disconnected();
+    val target = event["target"];
+
+    QWebSocketPrivate *wsp = reinterpret_cast<QWebSocketPrivate*>(target["data-context"].as<quintptr>());
+    Q_ASSERT (wsp);
+
+    emit wsp->q_func()->connected();
 }
 
-static void onErrorCallback(void *data, int message)
+static void q_onIncomingMessageCallback(val event)
 {
-    Q_UNUSED(message);
-    auto handler = reinterpret_cast<QWebSocketPrivate *>(data);
-    Q_ASSERT (handler);
-    emit handler->q_func()->error(handler->error());
+    val target = event["target"];
+
+    if (event["data"].typeOf().as<std::string>() == "string") {
+        QWebSocketPrivate *wsp = reinterpret_cast<QWebSocketPrivate*>(target["data-context"].as<quintptr>());
+        Q_ASSERT (wsp);
+
+        const QString message = QString::fromStdString(event["data"].as<std::string>());
+        if (!message.isEmpty())
+            wsp->q_func()->textMessageReceived(message);
+    } else {
+        val reader = val::global("FileReader").new_();
+        reader.set("onload", val::module_property("QWebSocketPrivate_readBlob"));
+        reader.set("data-context", target["data-context"]);
+        reader.call<void>("readAsArrayBuffer", event["data"]);
+    }
 }
 
-static void onIncomingMessageCallback(void *data, int message, int length, int dataType)
+static void q_readBlob(val event)
 {
-    QWebSocketPrivate *handler = reinterpret_cast<QWebSocketPrivate *>(data);
-    Q_ASSERT (handler);
-
-    QWebSocket *webSocket = handler->q_func();
-    const char *text = reinterpret_cast<const char *>(message);
-
-    switch (dataType) {
-    case 0: //string
-        webSocket->textMessageReceived(QLatin1String(text));
-        break;
-    case 1: //blob
-    case 2: //arraybuffer
-        webSocket->binaryMessageReceived(QByteArray::fromRawData(text, length));
-        break;
-    };
+    val fileReader = event["target"];
+
+    QWebSocketPrivate *wsp = reinterpret_cast<QWebSocketPrivate*>(fileReader["data-context"].as<quintptr>());
+    Q_ASSERT (wsp);
+
+    // Set up source typed array
+    val result = fileReader["result"]; // ArrayBuffer
+    val Uint8Array = val::global("Uint8Array");
+    val sourceTypedArray = Uint8Array.new_(result);
+
+    // Allocate and set up destination typed array
+    const size_t size = result["byteLength"].as<size_t>();
+    QByteArray buffer(size, Qt::Uninitialized);
+
+    val destinationTypedArray = Uint8Array.new_(val::module_property("HEAPU8")["buffer"],
+                                                reinterpret_cast<quintptr>(buffer.data()), size);
+    destinationTypedArray.call<void>("set", sourceTypedArray);
+
+    wsp->q_func()->binaryMessageReceived(buffer);
+}
+
+
+EMSCRIPTEN_BINDINGS(wasm_module) {
+    function("QWebSocketPrivate_onErrorCallback", q_onErrorCallback);
+    function("QWebSocketPrivate_onCloseCallback", q_onCloseCallback);
+    function("QWebSocketPrivate_onOpenCallback", q_onOpenCallback);
+    function("QWebSocketPrivate_onIncomingMessageCallback", q_onIncomingMessageCallback);
+    function("QWebSocketPrivate_readBlob", q_readBlob);
 }
 
 qint64 QWebSocketPrivate::sendTextMessage(const QString &message)
 {
-    EM_ASM_ARGS({
-        if (window.qWebSocket === undefined)
-            console.log("cannot find websocket object");
-        else
-            window.qWebSocket.send(Pointer_stringify($0));
-     }, message.toLocal8Bit().constData());
-
+    socketContext.call<void>("send", message.toStdString());
     return message.length();
 }
 
 qint64 QWebSocketPrivate::sendBinaryMessage(const QByteArray &data)
 {
-    g_messageArray = data;
-    EM_ASM({
-        if (window.qWebSocket === undefined) {
-            console.log("cannot find websocket object");
-        } else {
-            var array = Module.getBinaryMessage();
-            window.qWebSocket.binaryType = 'arraybuffer';
-            window.qWebSocket.send(array);
-        }
-    });
-
-    g_messageArray.clear();
+    socketContext.call<void>("send",
+                             val(typed_memory_view(data.size(),
+                                                   reinterpret_cast<const unsigned char *>
+                                                   (data.constData()))));
+
     return data.length();
 }
 
@@ -136,19 +148,10 @@ void QWebSocketPrivate::close(QWebSocketProtocol::CloseCode closeCode, QString r
     Q_Q(QWebSocket);
     m_closeCode = closeCode;
     m_closeReason = reason;
-    const quint16 closeReason = (quint16)closeCode;
     Q_EMIT q->aboutToClose();
-    QCoreApplication::processEvents();
-
-    EM_ASM_ARGS({
-        if (window.qWebSocket === undefined) {
-            console.log("cannot find websocket object");
-        } else {
-            var reasonMessage = Pointer_stringify($0);
-            window.qWebSocket.close($1, reasonMessage);
-            window.qWebSocket = undefined;
-        }
-    }, reason.toLatin1().data(), closeReason);
+
+    socketContext.call<void>("close", static_cast<quint16>(closeCode),
+                             reason.toLatin1().toStdString());
 }
 
 void QWebSocketPrivate::open(const QNetworkRequest &request, bool mask)
@@ -162,74 +165,21 @@ void QWebSocketPrivate::open(const QNetworkRequest &request, bool mask)
         return;
     }
 
-    QByteArray urlbytes = url.toString().toUtf8();
+    const std::string urlbytes = url.toString().toStdString();
 
     // HTML WebSockets do not support arbitrary request headers, but
     // do support the WebSocket protocol header. This header is
     // required for some use cases like MQTT.
-    QByteArray protocolHeaderValue = request.rawHeader("Sec-WebSocket-Protocol");
-
-    EM_ASM_ARGS({
-        if (window.qWebSocket != undefined)
-            return;
-
-        var wsUri = Pointer_stringify($0);
-        var wsProtocol = Pointer_stringify($1);
-        var handler = $2;
-        var onOpenCb = $3;
-        var onCloseCb = $4;
-        var onErrorCb = $5;
-        var onIncomingMessageCb = $6;
-
-        window.qWebSocket = wsProtocol.length > 0
-                           ? new WebSocket(wsUri, wsProtocol)
-                           : new WebSocket(wsUri);
-
-        window.qWebSocket.onopen = function(event) {
-            Runtime.dynCall('vi', onOpenCb, [handler]);
-        };
-
-        window.qWebSocket.onclose = function(event) {
-            window.qWebSocket = undefined;
-            Runtime.dynCall('vii', onCloseCb, [handler, event.code]);
-        };
-
-        window.qWebSocket.onerror = function(event) {
-            Runtime.dynCall('vii', onErrorCb, [handler, event.error]);
-        };
-
-        window.qWebSocket.onmessage = function(event) {
-            var outgoingMessage;
-            var bufferLength = 0;
-            var dataType;
-
-            if (window.qWebSocket.binaryType == 'arraybuffer' && typeof event.data == 'object') {
-
-                var byteArray = new Uint8Array(event.data);
-                bufferLength = byteArray.length;
-
-                outgoingMessage = _malloc(byteArray.length);
-                HEAPU8.set(byteArray, outgoingMessage);
-
-                dataType = 2;
-            } else if (typeof event.data == 'string') {
-                 dataType = 0;
-                 outgoingMessage = allocate(intArrayFromString(event.data), 'i8', ALLOC_NORMAL);
-            } else if (window.qWebSocket.binaryType == 'blob') {
-                 var byteArray = new Int8Array($0);
-                 outgoingMessage = new Blob(byteArray.buffer);
-                 dataType = 1;
-            }
-
-            Runtime.dynCall('viiii', onIncomingMessageCb, [handler, outgoingMessage, bufferLength, dataType]);
-            _free(outgoingMessage);
-        };
-
-    }, urlbytes.constData(),
-    protocolHeaderValue.data(),
-    this,
-    reinterpret_cast<void *>(onOpenCallback),
-    reinterpret_cast<void *>(onCloseCallback),
-    reinterpret_cast<void *>(onErrorCallback),
-    reinterpret_cast<void *>(onIncomingMessageCallback));
+    const std::string protocolHeaderValue = request.rawHeader("Sec-WebSocket-Protocol").toStdString();
+    val webSocket = val::global("WebSocket");
+
+    socketContext = !protocolHeaderValue.empty()
+            ? webSocket.new_(urlbytes, protocolHeaderValue)
+            : webSocket.new_(urlbytes);
+
+    socketContext.set("onerror", val::module_property("QWebSocketPrivate_onErrorCallback"));
+    socketContext.set("onclose", val::module_property("QWebSocketPrivate_onCloseCallback"));
+    socketContext.set("onopen", val::module_property("QWebSocketPrivate_onOpenCallback"));
+    socketContext.set("onmessage", val::module_property("QWebSocketPrivate_onIncomingMessageCallback"));
+    socketContext.set("data-context", val(quintptr(reinterpret_cast<void *>(this))));
 }