@gogoqiu/tencent-http-server 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/gogoqiu-node-http-service +3 -0
- package/dist/build.d.ts +3 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +3 -0
- package/dist/build.js.map +1 -0
- package/dist/routes/index.d.ts +4 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +106 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +318 -0
- package/dist/server.js.map +1 -0
- package/dist/serverCmd.d.ts +8 -0
- package/dist/serverCmd.d.ts.map +1 -0
- package/dist/serverCmd.js +44 -0
- package/dist/serverCmd.js.map +1 -0
- package/dist/shell/install.d.ts +5 -0
- package/dist/shell/install.d.ts.map +1 -0
- package/dist/shell/install.js +221 -0
- package/dist/shell/install.js.map +1 -0
- package/dist/shell/postinst.d.ts +2 -0
- package/dist/shell/postinst.d.ts.map +1 -0
- package/dist/shell/postinst.js +4 -0
- package/dist/shell/postinst.js.map +1 -0
- package/dist/shell.d.ts +2 -0
- package/dist/shell.d.ts.map +1 -0
- package/dist/shell.js +249 -0
- package/dist/shell.js.map +1 -0
- package/package.json +82 -0
- package/public/captures1//346/265/213/350/257/225/347/224/250captures +0 -0
- package/public/chat/offer.html +796 -0
- package/public/chat/options.html +58 -0
- package/public/chat/server-info.html +32 -0
- package/public/chat2.html +272 -0
- package/public/chat3.html +246 -0
- package/public/chat4.html +302 -0
- package/public/chat5.html +41 -0
- package/public/formdata.html +41 -0
- package/public/hls-player.htm +41 -0
- package/public/img/back.svg +1 -0
- package/public/img/offline.svg +1 -0
- package/public/img/online.svg +1 -0
- package/public/ip-record.html +28 -0
- package/public/js/encrypt.js +36 -0
- package/public/js/socket.io.min.js +7 -0
- package/public/js/socket.io.min.js.map +1 -0
- package/public/myhost/hostReg.html +35 -0
- package/public/mylog-chat.htm +260 -0
- package/public/mylog3.html +245 -0
- package/public/navbar.css +17 -0
- package/public/readme.txt +3 -0
- package/public/scroll.htm +139 -0
- package/public/ssh-client.html +0 -0
- package/public/upload-file.html +226 -0
- package/public/upload.html +23 -0
- package/public/uploads1/files-1757866537383-447469495.jpg +0 -0
- package/public/uploads1/files-1757867389485-764531720.jpg +0 -0
- package/public/uploads1/files-1757867518311-278635302.jpg +0 -0
- package/public/uploads1/files-1757867629687-688924576.jpg +0 -0
- package/public/uploads1/files-1757868630683-52261917.jpg +0 -0
- package/public/uploads1/files-1757869187061-619427683.jpg +0 -0
- package/public/uploads1/small_files-1757869187061-619427683.jpg +0 -0
- package/public/uploads1//346/265/213/350/257/225/347/224/250upload +0 -0
- package/public/utils.html +57 -0
- package/public/utils.js +161 -0
- package/public/webrtc/rtc-client.html +238 -0
- package/public/webrtc/rtc-file-transfer-client.html +238 -0
- package/public/webrtc/rtc-file-transfer-server.html +453 -0
- package/public/webrtc/rtc-server.html +453 -0
- package/public/webrtc/video-client-input.html +264 -0
- package/public/webrtc/video-server-input.html +312 -0
- package/public/webrtc/webrtc-chat-with-files.html +581 -0
- package/public/webrtc/webrtc-chat.html +367 -0
- package/public/webrtc/webrtc-file-offer.html +88 -0
- package/public/webrtc/webrtc1.html +186 -0
- package/readme.txt +71 -0
- package/views/chat.ejs +53 -0
- package/views/index.ejs +125 -0
- package/views/special-message.ejs +8 -0
- package/views/ssh.ejs +142 -0
- package/views/utils.ejs +0 -0
- package/views/webrtc/client.ejs +203 -0
- package/views/webrtc/server.ejs +365 -0
package/readme.txt
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
腾讯云,测试https/dns
|
|
2
|
+
|
|
3
|
+
npm install
|
|
4
|
+
npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
|
|
5
|
+
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
|
|
6
|
+
npm warn deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
|
|
7
|
+
npm warn deprecated rimraf@2.7.1: Rimraf versions prior to v4 are no longer supported
|
|
8
|
+
npm warn deprecated rollup-plugin-inject@3.0.2: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject.
|
|
9
|
+
|
|
10
|
+
那个是依赖inflight@1.0.6的,glob@7.2.3,sourcemap-codec@1.4.8,rimraf@2.7.1,rollup-plugin-inject@3.0.2
|
|
11
|
+
|
|
12
|
+
npm ls inflight
|
|
13
|
+
@gogoqiu/tencent-http-server@0.0.01 /mnt/data/init/git_spsp/nodejs2/tencent-cloud
|
|
14
|
+
└─┬ rollup-plugin-copy@3.5.0
|
|
15
|
+
└─┬ globby@10.0.1
|
|
16
|
+
└─┬ glob@7.2.3
|
|
17
|
+
└── inflight@1.0.6
|
|
18
|
+
|
|
19
|
+
nodejs的express如何配置https
|
|
20
|
+
|
|
21
|
+
注册域名
|
|
22
|
+
https://dash.domain.digitalplat.org/domains/gogoqiu.dpdns.org
|
|
23
|
+
gogoqiu.dpdns.org
|
|
24
|
+
https://dynv6.com/users/edit
|
|
25
|
+
gogoqiu.dns.navy
|
|
26
|
+
|
|
27
|
+
更新dns记录
|
|
28
|
+
https://dash.cloudflare.com/db76d31717b4cc48f56e5e38b6b0b54f/gogoqiu.dpdns.org/dns/records
|
|
29
|
+
|
|
30
|
+
更新dns本地记录
|
|
31
|
+
ipconfig /flushdns
|
|
32
|
+
The requested operation requires elevation.
|
|
33
|
+
sudo resolvectl flush-caches
|
|
34
|
+
|
|
35
|
+
dev-tools publish
|
|
36
|
+
tsc
|
|
37
|
+
npm publish
|
|
38
|
+
|
|
39
|
+
tsconfig.json(13,27): error TS5107: Option 'moduleResolution=node10' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '"ignoreDeprecations": "6.0"' to silence this error.
|
|
40
|
+
Visit https://aka.ms/ts6 for migration information.
|
|
41
|
+
->"moduleResolution": "node"=>"NodeNext",
|
|
42
|
+
tsconfig.json(26,15): error TS5110: Option 'module' must be set to 'NodeNext' when option 'moduleResolution' is set to 'NodeNext'.
|
|
43
|
+
->"module": "ESNext"=>"NodeNext",
|
|
44
|
+
|
|
45
|
+
港机只能使用npm原生仓库
|
|
46
|
+
npm config get registry
|
|
47
|
+
npm config set registry=https://packages.aliyun.com/6914934f15dfc6c86050a70d/npm/npm-registry/
|
|
48
|
+
npm login
|
|
49
|
+
npm publish --userconfig=/tmp/empty-npmrc --registry=https://registry.npmjs.org/
|
|
50
|
+
/home/gogoqiu/.npmrc
|
|
51
|
+
registry=https://registry.npmjs.org/
|
|
52
|
+
#//registry.npmjs.org/:_authToken=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
|
|
53
|
+
#//packages.aliyun.com/6914934f15dfc6c86050a70d/npm/npm-registry/:_authToken=29ad9728-9662-4b9c-9ac4-3e7c953493bb
|
|
54
|
+
@gogoqiu:registry=https://packages.aliyun.com/6914934f15dfc6c86050a70d/npm/npm-registry/
|
|
55
|
+
npm publish异常:
|
|
56
|
+
npm error 403 403 Forbidden - PUT https://registry.npmjs.org/@gogoqiu%2ftencent-http-server - Two-factor authentication or granular access token with bypass 2fa enabled is required to publish packages.
|
|
57
|
+
这意味着:即使你没有主动开启 Two-Factor Authentication(2FA),npm 现在强制要求对作用域包(scoped package,如 @gogoqiu/xxx)的发布操作必须使用 2FA 或支持 bypass 2FA 的细粒度 Token。
|
|
58
|
+
npm config set registry https://registry.npmjs.org/
|
|
59
|
+
package.json临时添加
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public",
|
|
62
|
+
"registry": "https://registry.npmjs.org/"
|
|
63
|
+
},
|
|
64
|
+
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
|
|
65
|
+
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
|
|
66
|
+
enable2FA
|
|
67
|
+
ade6fdd8b3e7ff1d26cfea73d2a49e597aa8ed644165d10ed432ea7bb22aa7b1
|
|
68
|
+
5021a3fb7b6cf70e65a3ca98c9367d549f67917b2675f73ce4eebfd7bbb601ed
|
|
69
|
+
38c7d277bff6f5efa94bfe186c47d12a4599dce896575743b9666fda42673e56
|
|
70
|
+
45d2adc8a0022253ee8a3896afd45cdd43ab1beb6769e94e4ab8db3508c151c7
|
|
71
|
+
c8c2effa5c9bac7bdd7d521d1863bf80d05916f9cc8669616fe14124627a5868
|
package/views/chat.ejs
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Socket.IO Chat</title>
|
|
5
|
+
<style>
|
|
6
|
+
body { font-family: Arial, sans-serif; }
|
|
7
|
+
#messages { list-style-type: none; margin: 0; padding: 0; }
|
|
8
|
+
#messages li { padding: 8px; margin-bottom: 2px; background-color: #f3f3f3; }
|
|
9
|
+
#form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
|
|
10
|
+
#input { border: none; padding: 10px; width: 90%; margin-right: .5%; }
|
|
11
|
+
#send { width: 9%; background: rgb(130, 224, 170); border: none; padding: 10px; }
|
|
12
|
+
</style>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
<ul id="messages"></ul>
|
|
16
|
+
<form id="form" action="">
|
|
17
|
+
<input id="input" autocomplete="off" /><button id="send">Send</button>
|
|
18
|
+
</form>
|
|
19
|
+
<!--只能引用public下的文件-->
|
|
20
|
+
<script src="/js/socket.io.min.js"></script>
|
|
21
|
+
<script>
|
|
22
|
+
/*
|
|
23
|
+
node-http-1/node_modules/socket.io/client-dist/socket.io.js
|
|
24
|
+
如何引用socket.io
|
|
25
|
+
node_modules一起发布
|
|
26
|
+
"ejs如何引用node_modules里的js"
|
|
27
|
+
app.use( '/', express.static( __dirname + '/www' ) );
|
|
28
|
+
要和$_DOCUMENT_ROOT对齐,只能放在$_DOCUMENT_ROOT以下的文件夹里
|
|
29
|
+
node_modules/socket.io/client-dist/socket.io.js 复制到 public/js 目录下。
|
|
30
|
+
*/
|
|
31
|
+
const socket = io();
|
|
32
|
+
|
|
33
|
+
const form = document.getElementById('form');
|
|
34
|
+
const input = document.getElementById('input');
|
|
35
|
+
const messages = document.getElementById('messages');
|
|
36
|
+
|
|
37
|
+
form.addEventListener('submit', function(e) {
|
|
38
|
+
e.preventDefault();
|
|
39
|
+
if (input.value) {
|
|
40
|
+
socket.emit('chat message', input.value);
|
|
41
|
+
input.value = '';
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
socket.on('chat message', function(msg) {
|
|
46
|
+
const item = document.createElement('li');
|
|
47
|
+
item.textContent = msg;
|
|
48
|
+
messages.appendChild(item);
|
|
49
|
+
window.scrollTo(0, document.body.scrollHeight);
|
|
50
|
+
});
|
|
51
|
+
</script>
|
|
52
|
+
</body>
|
|
53
|
+
</html>
|
package/views/index.ejs
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
<title>
|
|
2
|
+
<%= title %>
|
|
3
|
+
</title>
|
|
4
|
+
<style>
|
|
5
|
+
.board {
|
|
6
|
+
border: 1px solid black;
|
|
7
|
+
margin: 5px;
|
|
8
|
+
padding: 5px;
|
|
9
|
+
padding-left: 10px;
|
|
10
|
+
padding-right: 10px;
|
|
11
|
+
border-radius: 3px;
|
|
12
|
+
width: fit-content;
|
|
13
|
+
}
|
|
14
|
+
</style>
|
|
15
|
+
|
|
16
|
+
<body>
|
|
17
|
+
<div>
|
|
18
|
+
<a href="/av">AV Site</a>
|
|
19
|
+
<div>CHAT</div>
|
|
20
|
+
<div class="board">
|
|
21
|
+
<button onclick="goChat()">Chat1</button>
|
|
22
|
+
<button onclick="chat2()">Chat2</button>
|
|
23
|
+
<button onclick="chat3()">Chat3</button>
|
|
24
|
+
</div>
|
|
25
|
+
<div>WEBRTC</div>
|
|
26
|
+
<div class="board">
|
|
27
|
+
<button onclick="server()">ws-server</button>
|
|
28
|
+
<button onclick="client()">ws-client</button>
|
|
29
|
+
<button onclick="ws_room_server()">ws-room-server</button>
|
|
30
|
+
<button onclick="ws_room_client()">ws-room-client</button>
|
|
31
|
+
</div>
|
|
32
|
+
<div>MYLOG</div>
|
|
33
|
+
<div class="board">
|
|
34
|
+
<!--
|
|
35
|
+
日志离线版,日志以string[]的方式存放在使用的主机上,定时同步到后台
|
|
36
|
+
在线版
|
|
37
|
+
-->
|
|
38
|
+
<button onclick="mylog_chat()">日志序列版</button>
|
|
39
|
+
<button onclick="mylog()">日志文章版</button>
|
|
40
|
+
<button onclick="mylog3()">mylog3</button>
|
|
41
|
+
<button onclick="mylog3markdown()">mylog3markdown</button>
|
|
42
|
+
</div>
|
|
43
|
+
<div>HOSTS</div>
|
|
44
|
+
<div class="board">
|
|
45
|
+
<button onclick="hostsInfos()">主机连接信息</button>
|
|
46
|
+
</div>
|
|
47
|
+
<div>MISC</div>
|
|
48
|
+
<div class="board">
|
|
49
|
+
<button onclick="goUpload()">上传文件体验</button>
|
|
50
|
+
<button onclick="utils()">琐碎功能</button>
|
|
51
|
+
<button onclick="goLargeFileUpload()">上传大文件体验</button>
|
|
52
|
+
</div>
|
|
53
|
+
<div>VERSION<label id="version"></label></div>
|
|
54
|
+
</div>
|
|
55
|
+
<script>
|
|
56
|
+
function onload() {
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
window.onload = onload;
|
|
60
|
+
function goChat() {
|
|
61
|
+
window.location.href = "/chat";
|
|
62
|
+
}
|
|
63
|
+
function chat2() {
|
|
64
|
+
window.location.href = "/chat2.html";
|
|
65
|
+
}
|
|
66
|
+
function chat3() {
|
|
67
|
+
window.location.href = '/chat3.html';
|
|
68
|
+
}
|
|
69
|
+
function server() {
|
|
70
|
+
window.location.href = "/webrtc/server";
|
|
71
|
+
}
|
|
72
|
+
function client() {
|
|
73
|
+
window.location.href = "/webrtc/client";
|
|
74
|
+
}
|
|
75
|
+
function ws_room_server() {
|
|
76
|
+
window.location.href = "/rtc-server.html";
|
|
77
|
+
}
|
|
78
|
+
function ws_room_client() {
|
|
79
|
+
window.location.href = "/rtc-client.html";
|
|
80
|
+
}
|
|
81
|
+
function mylog_chat() {
|
|
82
|
+
window.location.href = "/mylog-chat.htm";
|
|
83
|
+
}
|
|
84
|
+
function mylog() {
|
|
85
|
+
window.location.href = "/mylog.html";
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function mylog3() {
|
|
89
|
+
// ws-mylog3
|
|
90
|
+
// 几个地方登录,看看获得的ip会不会串
|
|
91
|
+
window.location.href = "/mylog3.html";
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function mylog3markdown() {
|
|
95
|
+
// ws-mylog3
|
|
96
|
+
window.location.href = "/mylog3markdown.html";
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function hostsInfos() {
|
|
100
|
+
window.location.href = "/hosts/infos";
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function utils() {
|
|
104
|
+
window.location.href = "/utils.html";
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function goUpload() {
|
|
108
|
+
window.location.href = "/upload.html";
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function goLargeFileUpload() {
|
|
112
|
+
window.location.href = "/upload-file.html";
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function queryVersion() {
|
|
116
|
+
const version = await fetch("/version")
|
|
117
|
+
document.getElementById("version").innerText = version;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
queryVersion();
|
|
121
|
+
</script>
|
|
122
|
+
<style>
|
|
123
|
+
|
|
124
|
+
</style>
|
|
125
|
+
</body>
|
package/views/ssh.ejs
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>SSH 终端<%= hostname %></title>
|
|
6
|
+
<style>
|
|
7
|
+
body { margin: 0; padding: 0; }
|
|
8
|
+
#terminal {
|
|
9
|
+
width: 100%;
|
|
10
|
+
height: 100vh;
|
|
11
|
+
background-color: #000;
|
|
12
|
+
color: #fff;
|
|
13
|
+
font-family: monospace;
|
|
14
|
+
padding: 10px;
|
|
15
|
+
box-sizing: border-box;
|
|
16
|
+
overflow: auto;
|
|
17
|
+
}
|
|
18
|
+
</style>
|
|
19
|
+
<script src="/js/socket.io.min.js"></script>
|
|
20
|
+
</head>
|
|
21
|
+
<body>
|
|
22
|
+
<div>
|
|
23
|
+
<!--Host selector-->
|
|
24
|
+
<select id="host-selector">
|
|
25
|
+
<option value="aliyun">aliyun</option>
|
|
26
|
+
<option value="git">git</option>
|
|
27
|
+
</select>
|
|
28
|
+
<div>
|
|
29
|
+
<button onclick="connect()">Connect</button>"
|
|
30
|
+
<button onclick="close()">Close</button>"
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
<div id="terminal"></div>
|
|
34
|
+
|
|
35
|
+
<script>
|
|
36
|
+
/*
|
|
37
|
+
user: {
|
|
38
|
+
name: 'admin',
|
|
39
|
+
role: 'developer'
|
|
40
|
+
}
|
|
41
|
+
*/
|
|
42
|
+
const user = <%- JSON.stringify(user) %>;
|
|
43
|
+
/*
|
|
44
|
+
ts
|
|
45
|
+
编译到什么位置,可以引用...
|
|
46
|
+
dist
|
|
47
|
+
*/
|
|
48
|
+
function connect() {
|
|
49
|
+
socket.emit( "create ssh connection", {
|
|
50
|
+
host: "aliyun",
|
|
51
|
+
port: 22,
|
|
52
|
+
username: "root",
|
|
53
|
+
password: "password"
|
|
54
|
+
// privateKey: "privateKey"
|
|
55
|
+
} )
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function close() {
|
|
59
|
+
// 触发事件,触发事件以及附带消息
|
|
60
|
+
socket.emit( "close ssh connection", {} )
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const terminal = document.getElementById('terminal');
|
|
64
|
+
const socket = io();
|
|
65
|
+
|
|
66
|
+
// noraml
|
|
67
|
+
socket.on('ssh message', function(msg) {
|
|
68
|
+
let data
|
|
69
|
+
if (event.data instanceof Blob) {
|
|
70
|
+
const reader = new FileReader();
|
|
71
|
+
reader.onload = (e) => {
|
|
72
|
+
data = new TextDecoder('utf-8').decode(e.target.result);
|
|
73
|
+
// console.log( data, data.toString() )
|
|
74
|
+
terminal.innerHTML += data.replace(/\n/g, '<br>');
|
|
75
|
+
terminal.scrollTop = terminal.scrollHeight;
|
|
76
|
+
};
|
|
77
|
+
reader.readAsArrayBuffer(event.data);
|
|
78
|
+
//console.log( event.data )
|
|
79
|
+
} else if (typeof event.data === 'string') {
|
|
80
|
+
data = event.data;
|
|
81
|
+
console.log( data.charCodeAt(0) );
|
|
82
|
+
console.log( data )
|
|
83
|
+
const first = data.charCodeAt(0);
|
|
84
|
+
const found = data.indexOf( `gogoqiu@notepad:`);
|
|
85
|
+
if( first == 7 || first == 8 )
|
|
86
|
+
terminal.innerHTML = terminal.innerHTML.slice(0, -1);
|
|
87
|
+
else if( first == 27 && found >= 0 ){
|
|
88
|
+
data = data.substring( found );
|
|
89
|
+
terminal.innerHTML += data.replace(/\n/g, '<br>');
|
|
90
|
+
}else if( first == 27 || first == 13 ){
|
|
91
|
+
//忽略乱码
|
|
92
|
+
}else
|
|
93
|
+
terminal.innerHTML += data.replace(/\n/g, '<br>');
|
|
94
|
+
terminal.scrollTop = terminal.scrollHeight;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
socket.on('ssh error', function(msg){
|
|
99
|
+
alert(msg);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// 处理键盘输入
|
|
103
|
+
document.addEventListener('keydown', (event) => {
|
|
104
|
+
event.preventDefault();
|
|
105
|
+
|
|
106
|
+
// 处理特殊按键
|
|
107
|
+
if (event.key === 'Enter') {
|
|
108
|
+
ws.send('\r'); // 发送换行符
|
|
109
|
+
terminal.innerHTML += '<br>';
|
|
110
|
+
} else if (event.key === 'Backspace') {
|
|
111
|
+
//ws.send('\x7F'); // 发送退格符
|
|
112
|
+
//ws.send( '\x08' )
|
|
113
|
+
socket.emit( "", '\x08' )
|
|
114
|
+
// 删除终端中的最后一个字符
|
|
115
|
+
//terminal.innerHTML = terminal.innerHTML.slice(0, -1);
|
|
116
|
+
} else if (event.key === 'Tab') {
|
|
117
|
+
//ws.send('\t'); // 发送制表符
|
|
118
|
+
socket.emit( "", '\t' )
|
|
119
|
+
} else if (event.key.length === 1) {
|
|
120
|
+
// 普通字符
|
|
121
|
+
//ws.send(event.key);
|
|
122
|
+
socket.emit( "", event.key )
|
|
123
|
+
// 避免现在加入,其实需要onmessage中加入
|
|
124
|
+
//terminal.innerHTML += event.key;
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// 连接状态
|
|
129
|
+
ws.onopen = () => {
|
|
130
|
+
terminal.innerHTML = '已连接到 SSH 服务器<br>';
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
ws.onclose = () => {
|
|
134
|
+
terminal.innerHTML += '<br>连接已关闭';
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
ws.onerror = (error) => {
|
|
138
|
+
terminal.innerHTML += `<br>连接错误: ${error.message}`;
|
|
139
|
+
};
|
|
140
|
+
</script>
|
|
141
|
+
</body>
|
|
142
|
+
</html>
|
package/views/utils.ejs
ADDED
|
File without changes
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<meta name="description" content="WebRTC code samples">
|
|
7
|
+
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1, maximum-scale=1">
|
|
8
|
+
<meta itemprop="description" content="Client-side WebRTC code samples">
|
|
9
|
+
<meta itemprop="image" content="../../../images/webrtc-icon-192x192.png">
|
|
10
|
+
<meta itemprop="name" content="WebRTC code samples">
|
|
11
|
+
<meta name="mobile-web-app-capable" content="yes">
|
|
12
|
+
<meta id="theme-color" name="theme-color" content="#ffffff">
|
|
13
|
+
|
|
14
|
+
<base target="_blank">
|
|
15
|
+
|
|
16
|
+
<title>Video to peer connection</title>
|
|
17
|
+
|
|
18
|
+
<script src="/js/socket.io.min.js"></script>
|
|
19
|
+
</head>
|
|
20
|
+
|
|
21
|
+
<body>
|
|
22
|
+
|
|
23
|
+
<div id="container">
|
|
24
|
+
<P><a href="/">CLIENT</a></P>
|
|
25
|
+
<div id="log"></div>
|
|
26
|
+
<video id="rightVideo" autoplay controls></video>
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<script>
|
|
31
|
+
|
|
32
|
+
'use strict';
|
|
33
|
+
|
|
34
|
+
//var leftVideo = document.getElementById('leftVideo');
|
|
35
|
+
var rightVideo = document.getElementById('rightVideo');
|
|
36
|
+
|
|
37
|
+
var stream;
|
|
38
|
+
|
|
39
|
+
//var pc1;
|
|
40
|
+
var pc2;
|
|
41
|
+
|
|
42
|
+
var startTime;
|
|
43
|
+
|
|
44
|
+
/*
|
|
45
|
+
也能部署在php下,只要广播能用
|
|
46
|
+
*/
|
|
47
|
+
rightVideo.onloadedmetadata = function () {
|
|
48
|
+
console.log('Remote video videoWidth: ' + this.videoWidth +
|
|
49
|
+
'px, videoHeight: ' + this.videoHeight + 'px');
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
rightVideo.onresize = function () {
|
|
53
|
+
console.log('Remote video size changed to ' +
|
|
54
|
+
rightVideo.videoWidth + 'x' + rightVideo.videoHeight);
|
|
55
|
+
// We'll use the first onresize callback as an indication that
|
|
56
|
+
// video has started playing out.
|
|
57
|
+
if (startTime) {
|
|
58
|
+
var elapsedTime = window.performance.now() - startTime;
|
|
59
|
+
console.log('Setup time: ' + elapsedTime.toFixed(3) + 'ms');
|
|
60
|
+
startTime = null;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
rightVideo.onerror = function (err) {
|
|
64
|
+
console.log(err);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const socket = io();
|
|
68
|
+
const hostId = new Date().getTime();
|
|
69
|
+
|
|
70
|
+
//会导致connected=false,然后无法emit信息
|
|
71
|
+
//socket.onconnect = function(){ console.log(arguments) }
|
|
72
|
+
|
|
73
|
+
/*
|
|
74
|
+
server/client共有的部分
|
|
75
|
+
socket.on('ice-candidate', ...
|
|
76
|
+
pc2 = new RTCPeerConnection(configuration);
|
|
77
|
+
*/
|
|
78
|
+
socket.on('webrtc ice-candidate', function (msg) {
|
|
79
|
+
//socket.emit('ice-candidate', { host:hostId, candidate: event.candidate})
|
|
80
|
+
//msg.candidate
|
|
81
|
+
if (msg.host != hostId) {
|
|
82
|
+
//pc1.addIceCandidate( msg.candidate )
|
|
83
|
+
pc2.addIceCandidate(msg.candidate)
|
|
84
|
+
.then(() => {
|
|
85
|
+
console.log('addIceCandidate success', msg.candidate)
|
|
86
|
+
})
|
|
87
|
+
.catch(function (err) {
|
|
88
|
+
console.error('Error adding candidate:' + err)
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// 互作为候选
|
|
92
|
+
console.log("webrtc ice-candidate", msg)
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
/*
|
|
96
|
+
console日志
|
|
97
|
+
client:94 got offer
|
|
98
|
+
client:88 {host: 1756610925562, candidate: {…}}
|
|
99
|
+
# pc2.ontrack
|
|
100
|
+
client:146 got remote stream RTCTrackEvent {isTrusted: true, receiver: RTCRtpReceiver, track: MediaStreamTrack, streams: Array(1), transceiver: RTCRtpTransceiver, …}
|
|
101
|
+
client:150 pc2 received remote stream RTCTrackEvent {isTrusted: true, receiver: RTCRtpReceiver, track: MediaStreamTrack, streams: Array(1), transceiver: RTCRtpTransceiver, …}
|
|
102
|
+
client:146 got remote stream RTCTrackEvent {isTrusted: true, receiver: RTCRtpReceiver, track: MediaStreamTrack, streams: Array(1), transceiver: RTCRtpTransceiver, …}
|
|
103
|
+
# get offer
|
|
104
|
+
client:96 !!!!!!setRemoteDescription ok
|
|
105
|
+
client:88 {host: 1756610925562, candidate: {…}}
|
|
106
|
+
client:88 {host: 1756610925562, candidate: {…}}
|
|
107
|
+
client:82 addIceCandidate success {candidate: 'candidate:572777746 1 udp 2113937151 b7428094-a070…typ host generation 0 ufrag YePK network-cost 999', sdpMid: '0', sdpMLineIndex: 0, usernameFragment: 'YePK'}
|
|
108
|
+
client:101 !!!!!!setLocalDescription ok
|
|
109
|
+
client:88 {host: 1756610925562, candidate: {…}}
|
|
110
|
+
client:82 addIceCandidate success {candidate: 'candidate:1225858760 1 udp 2113939711 68ed024d-4df…typ host generation 0 ufrag YePK network-cost 999', sdpMid: '0', sdpMLineIndex: 0, usernameFragment: 'YePK'}
|
|
111
|
+
client:82 addIceCandidate success {candidate: 'candidate:572777746 1 udp 2113937151 b7428094-a070…typ host generation 0 ufrag YePK network-cost 999', sdpMid: '1', sdpMLineIndex: 1, usernameFragment: 'YePK'}
|
|
112
|
+
client:138 ICE state change event: Event {isTrusted: true, type: 'iceconnectionstatechange', target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2, …}
|
|
113
|
+
client:138 ICE state change event: Event {isTrusted: true, type: 'iceconnectionstatechange', target: RTCPeerConnection, currentTarget: RTCPeerConnection, eventPhase: 2, …}
|
|
114
|
+
client:50 Remote video size changed to 640x360
|
|
115
|
+
client:45 Remote video videoWidth: 640px, videoHeight: 360px
|
|
116
|
+
client:50 Remote video size changed to 640x360
|
|
117
|
+
client:82 addIceCandidate success {candidate: 'candidate:1225858760 1 udp 2113939711 68ed024d-4df…typ host generation 0 ufrag YePK network-cost 999', sdpMid: '1', sdpMLineIndex: 1, usernameFragment: 'YePK'}
|
|
118
|
+
client:50 Remote video size changed to 960x540
|
|
119
|
+
client:50 Remote video size changed to 1280x720
|
|
120
|
+
Remote video size changed to 1280x720, 说明视频信息到位了
|
|
121
|
+
*/
|
|
122
|
+
// server create offer, so ignore?
|
|
123
|
+
// add desc immediately, not from server
|
|
124
|
+
/*
|
|
125
|
+
webrtc不叫服务器端,而是叫offer端
|
|
126
|
+
*/
|
|
127
|
+
socket.on('webrtc offer', function (desc) {
|
|
128
|
+
console.log('got offer', "offer desc", desc)
|
|
129
|
+
//
|
|
130
|
+
pc2.setRemoteDescription(desc, function () {
|
|
131
|
+
// offer description
|
|
132
|
+
console.log('!!!!!!setRemoteDescription ok');
|
|
133
|
+
}, (error) => console.error('Failed to set session description: ' + error.toString()));
|
|
134
|
+
//console.log(desc)
|
|
135
|
+
pc2.createAnswer((desc) => {
|
|
136
|
+
// answer with client description
|
|
137
|
+
pc2.setLocalDescription(desc, function () {
|
|
138
|
+
console.log('!!!!!!setLocalDescription ok');
|
|
139
|
+
}, (error) => console.log('Failed to set session description: ' + error.toString())
|
|
140
|
+
);
|
|
141
|
+
// 特定类型的消息
|
|
142
|
+
socket.emit('webrtc answer', desc);
|
|
143
|
+
},
|
|
144
|
+
(error) => console.log('Failed to create session description: ' + error.toString()));
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
socket.on('webrtc answer', function (desc) {
|
|
148
|
+
//pc1.setRemoteDescription(desc)
|
|
149
|
+
console.log(desc)
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const configuration = {
|
|
153
|
+
iceServers: [
|
|
154
|
+
//stun协议服务器。反馈外网信息
|
|
155
|
+
{ urls: 'stun:stun.l.google.com:19302' },
|
|
156
|
+
/*
|
|
157
|
+
{
|
|
158
|
+
urls: 'turn:yourturnserver.com:3478',
|
|
159
|
+
username: 'yourusername',
|
|
160
|
+
credential: 'yourpassword'
|
|
161
|
+
}*/
|
|
162
|
+
]
|
|
163
|
+
};
|
|
164
|
+
// 获得外网信息?
|
|
165
|
+
pc2 = new RTCPeerConnection(configuration);
|
|
166
|
+
pc2.onicecandidate = function (event) {
|
|
167
|
+
/*
|
|
168
|
+
// 获得ice信息后通过服务器发送给对端
|
|
169
|
+
server:
|
|
170
|
+
socket.on('ice-candidate'
|
|
171
|
+
*/
|
|
172
|
+
socket.emit('webrtc ice-candidate', { host: hostId, candidate: event.candidate });
|
|
173
|
+
};
|
|
174
|
+
pc2.oniceconnectionstatechange = function (e) {
|
|
175
|
+
console.log('ICE state change event: ', e);
|
|
176
|
+
};
|
|
177
|
+
/*
|
|
178
|
+
接收到直连mediastream
|
|
179
|
+
RTCPeerConnection的ontrack事件什么时候发生
|
|
180
|
+
1.远程端已添加媒体轨道并发送
|
|
181
|
+
远程端通过 addTrack() 方法将媒体轨道(MediaStreamTrack)添加到 RTCPeerConnection,
|
|
182
|
+
并通过 SDP 会话描述(setLocalDescription/setRemoteDescription)和 ICE 候选交换完成连接建立。
|
|
183
|
+
2.本地端成功接收并解析远程媒体流
|
|
184
|
+
当本地端通过信令服务器收到远程端的 SDP 和 ICE 候选,且 WebRTC 连接成功建立后,远程媒体流会被传输到本地,此时触发 ontrack 事件。
|
|
185
|
+
*/
|
|
186
|
+
pc2.ontrack = gotRemoteStream;
|
|
187
|
+
|
|
188
|
+
function gotRemoteStream(event) {
|
|
189
|
+
console.log('got remote stream', event);
|
|
190
|
+
// 会不会触发onresize
|
|
191
|
+
if (rightVideo.srcObject !== event.streams[0]) {
|
|
192
|
+
// video控件竟然支持碎片解析播放
|
|
193
|
+
// 绑定
|
|
194
|
+
rightVideo.srcObject = event.streams[0];
|
|
195
|
+
console.log('pc2 received remote stream', event);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
</script>
|
|
200
|
+
|
|
201
|
+
</body>
|
|
202
|
+
|
|
203
|
+
</html>
|