เมื่อเร็ว ๆ นี้เนื่องจากความต้องการของโครงการฉันได้ศึกษาการใช้งาน WebSocket ของ nodejs, socket.io ซึ่งเป็นเฟรมเวิร์กที่ใช้กันอย่างแพร่หลายโดยแอปพลิเคชันพื้นหลังของ NodeJS WebSocket
การตระเตรียม
1. ติดตั้ง socket.io และใช้คำสั่ง npm socket.io
2. สำหรับระบบ Windows จำเป็นต้องมีสภาพแวดล้อมการรวบรวม VC เนื่องจากเมื่อติดตั้ง socket.io รหัส VC จะถูกรวบรวม
หลักการพื้นฐานของเกม
1. เซิร์ฟเวอร์ฟังการเชื่อมต่อของลูกค้า
2. เมื่อการเชื่อมต่อไคลเอนต์สำเร็จแล้วหน้าการเชื่อมโยงจะย้ายเหตุการณ์เมาส์และพิกัดปัจจุบันจะถูกส่งไปยังเซิร์ฟเวอร์
3. เซิร์ฟเวอร์บันทึกวัตถุพิกัดส่วนกลางและใช้หมายเลขที่ไม่ซ้ำของไคลเอ็นต์เป็นค่าคีย์
4. เมื่อมีการเชื่อมต่อใหม่ออกอากาศพิกัดไปยังลูกค้ารายอื่น
5. เมื่อไคลเอนต์ถูกตัดการเชื่อมต่อเซิร์ฟเวอร์จะลบข้อมูลพิกัดและออกอากาศไปยังไคลเอนต์อื่น ๆ
เริ่มใช้รหัสเซิร์ฟเวอร์
เมื่อ scoket.io สร้างการตรวจสอบเซิร์ฟเวอร์มันจำเป็นต้องพึ่งพาการเชื่อมต่อ HTTP เพื่อจัดการโปรโตคอลการอัพเกรดดังนั้นจึงต้องใช้โมดูล HTTP รหัสมีดังนี้:
การคัดลอกรหัสมีดังนี้:
var http = reghed ('http')
io = ต้องการ ('socket.io');
var app = http.createServer (). ฟัง (9091);
var ws = io.listen (แอป);
จากนั้นกำหนดวัตถุพิกัดทั่วโลก
การคัดลอกรหัสมีดังนี้:
โพสต์ var = {};
เริ่มฟังการเชื่อมต่อของลูกค้าและเพิ่มฟังก์ชั่นการออกอากาศใหม่ (อันที่จริงคุณสามารถใช้วิธีการออกอากาศ io.sockets.broadcast.emit ซึ่งมาพร้อมกับ socket.io) และรหัสหลักมีดังนี้:
การคัดลอกรหัสมีดังนี้:
ws.on ('การเชื่อมต่อ', ฟังก์ชั่น (ไคลเอนต์) {
// ฟังก์ชั่นการออกอากาศ
var broadcast = function (msg, cl) {
สำหรับ (var k ใน ws.sockets.sockets) {
if (ws.sockets.sockets.hasownproperty (k)) {
if (ws.sockets.sockets [k] && ws.sockets.sockets [k] .id! = cl.id) {
ws.sockets.sockets [k] .emit ('position.change', ผงชูรส);
-
-
-
-
console.log ('/033 [92m มีการเชื่อมต่อใหม่:/033 [39m', โพสต์);
// หลังจากการเชื่อมต่อลูกค้าสำเร็จข้อมูลประสานงานของลูกค้ารายอื่นจะถูกส่ง
client.emit ('position.change', โพสต์);
// รับลูกค้าส่งข้อความ
client.on ('position.change', function (msg) {
// ปัจจุบันข้อความของลูกค้าเป็นข้อความประสานงานเท่านั้น
ตำแหน่ง [client.id] = msg;
// ข้อความออกอากาศไปยังลูกค้าอื่น ๆ ทั้งหมด
ออกอากาศ({
ประเภท: 'ตำแหน่ง',
โพสต์: ผงชูรส
id: client.id
}, ลูกค้า);
-
// รับข้อความการเชื่อมต่อการปิดไคลเอนต์
client.on ('close', function () {
console.log ('ปิด!');
// ลบลูกค้าและแจ้งลูกค้าอื่น ๆ
ลบตำแหน่ง [client.id];
// ข้อความออกอากาศไปยังลูกค้าอื่น ๆ ทั้งหมด
ออกอากาศ({
ประเภท: 'ตัดการเชื่อมต่อ',
id: client.id
}, ลูกค้า);
-
// ตัดการเชื่อมต่อ
client.on ('disconnect', function () {
console.log ('ตัดการเชื่อมต่อ!');
// ลบลูกค้าและแจ้งลูกค้าอื่น ๆ
ลบตำแหน่ง [client.id];
// ข้อความออกอากาศไปยังลูกค้าอื่น ๆ ทั้งหมด
ออกอากาศ({
ประเภท: 'ตัดการเชื่อมต่อ',
id: client.id
}, ลูกค้า);
-
// กำหนดการจัดการข้อยกเว้นของลูกค้า
client.on ('ข้อผิดพลาด', ฟังก์ชั่น (err) {
console.log ('ข้อผิดพลาด->', err);
-
-
จุดสำคัญของการวิเคราะห์รหัสด้านบนคือ
1. ไคลเอนต์ใหม่เชื่อมต่อสำเร็จและมีการส่งข้อมูลพิกัดของลูกค้ารายอื่น
2. เมื่อลูกค้าอัปเดตข้อมูลพิกัดแจ้งลูกค้าอื่น ๆ
3. ลูกค้าตัดการเชื่อมต่อและแจ้งลูกค้าอื่น ๆ
4. ประเภทข้อความออกอากาศแบ่งออกเป็นพิกัดและการลบพิกัด
เขียนหน้าไคลเอนต์ HTML
เนื่องจาก socket.io เป็นกรอบการทำงานที่กำหนดเองลูกค้าจึงจำเป็นต้องอ้างถึง socket.io.js JS นี้สามารถพบได้จากโมดูลซ็อกเก็ต เส้นทางโดยทั่วไปคือ node_modules/socket.io/node_modules/socket.io-client/dist มีสองเวอร์ชันของการผสานและการบีบอัด คุณสามารถใช้เวอร์ชันการผสานระหว่างการพัฒนา
รหัสที่สมบูรณ์มีดังนี้:
การคัดลอกรหัสมีดังนี้:
<! doctype html>
<html>
<head>
<title> socket.io ตัวอย่างของการโต้ตอบออนไลน์ของผู้คนหลายคนพร้อมกัน </title>
<meta charset = "utf-8">
</head>
<body>
<script type = "text/javascript" src = "socket.io.js"> </script>
<script type = "text/javascript">
var ws = io.connect ('http: // localhost: 9091/');
var isfirst;
ws.on ('Connect', function () {
console.log (ws);
// เริ่มเหตุการณ์ Mousemove ที่มีผลผูกพัน
document.onmousemove = function (ev) {
if (ws.socket.transport.isopen) {
ws.emit ('position.change', {x: ev.clientx, y: ev.clienty});
-
-
-
ws.on ('position.change', ฟังก์ชั่น (ข้อมูล) {
// เริ่มออนไลน์ในเวลาเดียวกัน
ถ้า (! isfirst) {
isfirst = true;
// ข้อความแรกคือการรับพิกัดของลูกค้าอื่น ๆ ทั้งหมด
สำหรับ (var i ในข้อมูล) {
ย้าย (i, data [i]);
-
}อื่น{
// มิฉะนั้นจะเป็นข้อความที่ตัดการเชื่อมต่อหรือข้อความที่อัปเดต
if ('ตำแหน่ง' == data.type) {
ย้าย (data.id, data.post);
}อื่น{
ลบ (data.id);
-
-
-
ws.on ('ข้อผิดพลาด', function () {
console.log ('ข้อผิดพลาด:', ws);
ws.disconnect ();
-
ฟังก์ชั่นย้าย (id, pos) {
var ele = document.querySelector ('#cursor_' + id);
ถ้า (! ele) {
// หากไม่มีอยู่จริงมันจะถูกสร้างขึ้น
ele = document.createElement ('img');
ele.id = 'Cursor_' + id;
Ele.src = 'img/cursor.png';
Ele.style.position = 'Absolute';
document.body.appendchild (ele);
-
Ele.style.left = pos.x + 'px';
Ele.style.top = pos.y + 'px';
-
ฟังก์ชั่นลบ (id) {
var ele = document.querySelector ('#cursor_' + id);
Ele.ParentNode.removeChild (Ele);
-
</script>
</body>
</html>
img/cursor.png บนหน้าสามารถพบได้ที่นี่, cursor.png และมีไอคอนเมาส์อื่น ๆ อีกมากมายที่นี่ หลักการของส่วนหน้าค่อนข้างง่าย การวิเคราะห์อย่างง่ายมีดังนี้
1. เมื่อการเชื่อมต่อสำเร็จให้ผูกเหตุการณ์ Mousemove บนหน้าและส่งข้อความพิกัดใหม่
2. ได้รับข้อความตามประเภทข้อความจำเป็นต้องแก้ไขข้อความไคลเอนต์อื่น ๆ หรือลบข้อความไคลเอนต์อื่น ๆ หรือไม่?
3. กำหนดไอคอนเคอร์เซอร์ไคลเอนต์อื่น ๆ และลบไอคอนเคอร์เซอร์
4. ประมวลผลข้อความข้อยกเว้นไคลเอนต์และเพิ่มการตัดการเชื่อมต่อเพื่อให้เซิร์ฟเวอร์ลบข้อมูลพิกัด
ตัวอย่างการรัน
1. บันทึกรหัสเซิร์ฟเวอร์เป็น io_multigame.js
2. บันทึกรหัสไคลเอนต์เป็น io_multigame.html
3. เรียกใช้รหัสเซิร์ฟเวอร์โหนด io_multigame.js
4. เปิดหน้า io_multigame.html หลายหน้าเพื่อดูเอฟเฟกต์
สรุป
การเขียนค่อนข้างไม่เป็นทางการและอ้างอิงถึง NodeJ ที่น่าทึ่ง นี่เป็นหนังสือที่ดี เพื่อนที่ต้องการรู้ว่า NodeJS สามารถอ่านหนังสือเล่มนี้ได้