Skip to content

Commit

Permalink
[unreal]添加websocket的支持
Browse files Browse the repository at this point in the history
  • Loading branch information
chexiongsheng committed Aug 22, 2024
1 parent 04a7c85 commit 5f8cf10
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 0 deletions.
144 changes: 144 additions & 0 deletions unreal/Puerts/Content/JavaScript/puerts/websocketpp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* Tencent is pleased to support the open source community by making Puerts available.
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
* Puerts is licensed under the BSD 3-Clause License, except for the third-party components listed in the file 'LICENSE' which may be subject to their corresponding license terms.
* This file is subject to the terms and conditions defined in file 'LICENSE', which is part of this source code package.
*/

var global = global || (function () { return this; }());
(function (global) {
const WebSocketPP = global.WebSocketPP;
//global.WebSocketPP = undefined;

class EventTarget {
constructor() {
this.listeners = {};
}

addEventListener(type, callback) {
if (!(type in this.listeners)) {
this.listeners[type] = [];
}
this.listeners[type].push(callback);
}

removeEventListener(type, callback) {
if (!(type in this.listeners)) {
return;
}
const stack = this.listeners[type];
for (let i = 0; i < stack.length; i++) {
if (stack[i] === callback) {
stack.splice(i, 1);
return;
}
}
}

dispatchEvent(ev) {
if (!(ev.type in this.listeners)) {
return true;
}
const stack = this.listeners[ev.type].slice();

for (let i = 0; i < stack.length; i++) {
stack[i].call(this, ev);
}
return !ev.defaultPrevented;
}
}

const readyStates = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'];

const poll_ws_objects = [];

class WebSocket extends EventTarget {
constructor(url, protocols) {
super();
if (protocols) throw new Error('do not support protocols argument');
this._raw = new WebSocketPP(url);
this._url = url;
// !!do not raise exception in handles.
this._raw.setHandles(
()=> {
this._readyState = WebSocket.OPEN;
this._addPendingEvent({type:'open'});
},
(data) => {
this._addPendingEvent({type:'message', data:data, origin:this._url});
},
(code, reason) => {
this._cleanup();
this._addPendingEvent({type:'close', code:code, reason: reason});
},
() => {
this._addPendingEvent({type:'error'});
this._cleanup();
this._addPendingEvent({type:'close', code:1006, reason: ""});
});

this._readyState = WebSocket.CONNECTING;
this._tid = setInterval(() => this._poll(), 1);
this._pendingEvents = [];
}

get url() {
return this._url;
}

get readyState() {
return this._readyState;
}

send(data) {
if (this._readyState !== WebSocket.OPEN) {
throw new Error(`WebSocket is not open: readyState ${this._readyState} (${readyStates[this._readyState]})`);
}
this._raw.send(data);
}

_cleanup() {
this._readyState = WebSocket.CLOSING;
}

_addPendingEvent(ev) {
this._pendingEvents.push(ev);
}

_poll() {
if (this._pendingEvents.length === 0 && this._readyState != WebSocket.CLOSING) {
this._raw.poll();
}
const ev = this._pendingEvents.shift();
if (ev) this.dispatchEvent(ev);
if (this._pendingEvents.length === 0 && this._readyState == WebSocket.CLOSING) {
this._raw = undefined;
clearInterval(this._tid);
this._readyState = WebSocket.CLOSED;
}
}

close(code, data) {
try {
this._raw.close(code, data);
} catch(e) {}
this._cleanup();
}

}

for (let i = 0; i < readyStates.length; i++) {
Object.defineProperty(WebSocket, readyStates[i], {
enumerable: true,
value: i
});

Object.defineProperty(WebSocket.prototype, readyStates[i], {
enumerable: true,
value: i
});
}

global.WebSocket = WebSocket;

}(global));
7 changes: 7 additions & 0 deletions unreal/Puerts/Source/JsEnv/JsEnv.Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ enum SupportedV8Versions
public static bool WithSourceControl = false;

public bool WithByteCode = false;

private bool WithWebsocket = false;

public JsEnv(ReadOnlyTargetRules Target) : base(Target)
{
Expand All @@ -67,6 +69,11 @@ public JsEnv(ReadOnlyTargetRules Target) : base(Target)
PublicDefinitions.Add("PUERTS_WITH_EDITOR_SUFFIX");
}

if (WithWebsocket)
{
PublicDefinitions.Add("WITH_WEBSOCKET");
}

ShadowVariableWarningLevel = WarningLevel.Warning;

if (!FTextAsString)
Expand Down
9 changes: 9 additions & 0 deletions unreal/Puerts/Source/JsEnv/Private/JsEnvImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ PRAGMA_ENABLE_UNDEFINED_IDENTIFIER_WARNINGS
#include "PuertsWasm/WasmJsFunctionParams.h"
#endif

#if defined(WITH_WEBSOCKET)
void InitWebsocketPPWrap(v8::Local<v8::Context> Context);
#endif

namespace PUERTS_NAMESPACE
{
#if !defined(WITH_QUICKJS)
Expand Down Expand Up @@ -669,6 +673,11 @@ FJsEnvImpl::FJsEnvImpl(std::shared_ptr<IJSModuleLoader> InModuleLoader, std::sha
delete CachedCode; //编辑器下是v8.dll分配的,ue里的delete被重载了,这delete会有问题
#endif
#endif

#if defined(WITH_WEBSOCKET)
InitWebsocketPPWrap(Context);
ExecuteModule("puerts/websocketpp.js");
#endif
}

// #lizard forgives
Expand Down

0 comments on commit 5f8cf10

Please sign in to comment.