از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
نمونههای Node.js Websocket با Socket.io در چند سال گذشته، نوع جدیدی از ارتباطات شروع به ظهور کرد. روی وب و در برنامه های تلفن همراه، به نام وب سوکت. این پروتکل مدت ها مورد انتظار بود و سرانجام در سال 2011 توسط IETF استاندارد شد و راه را برای استفاده گسترده هموار کرد. این پروتکل جدید خیلی سریعتر باز می شود…
سرفصلهای مطلب
وب سوکت ها چیست؟
در چند سال گذشته، نوع جدیدی از ارتباطات شروع به ظهور کرد روی وب و در برنامه های تلفن همراه، نامیده می شود سوکت های وب. این پروتکل مدت ها مورد انتظار بود و سرانجام در سال 2011 توسط IETF استاندارد شد و راه را برای استفاده گسترده هموار کرد.
این پروتکل جدید یک خط ارتباطی بسیار سریعتر و کارآمدتر را برای مشتری باز می کند. مانند HTTP، سوکتهای وب اجرا میشوند روی بالای یک اتصال TCP، اما آنها بسیار سریعتر هستند، زیرا ما مجبور نیستیم برای هر بار که میخواهیم پیامی ارسال کنیم، یک اتصال جدید باز کنیم، زیرا اتصال تا زمانی که سرور یا کلاینت بخواهد زنده نگه داشته میشود.
حتی بهتر از آن، از آنجایی که اتصال هرگز از بین نمیرود، در نهایت ارتباط تمام دوبلکس در دسترس ما است، یعنی میتوانیم به جای اینکه منتظر بمانید تا آنها از سرور درخواست اطلاعات کنند، داده ها را به مشتری فشار دهید. این اجازه می دهد تا داده ها به عقب و جلو منتقل شوند، که برای مواردی مانند برنامه های چت بلادرنگ یا حتی بازی ها ایده آل است.
وب سوکت ها چگونه کار می کنند؟
در هسته خود، یک وب سوکت فقط یک اتصال TCP است که امکان ارتباط دوطرفه کامل را فراهم می کند، به این معنی که هر طرف اتصال می تواند داده ها را حتی در همان زمان به دیگری ارسال کند.
برای برقراری این ارتباط، پروتکل در واقع دست دادن را به عنوان یک درخواست HTTP معمولی آغاز می کند، اما سپس با استفاده از درخواست ارتقا هدر HTTP، مانند این:
GET /ws/chat HTTP/1.1
Host: chat.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: q1PZLMeDL4EwLkw4GGhADm==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 15
Origin: http://example.com
سپس سرور یک پاسخ HTTP 101 “Switching Protocols” را ارسال می کند و تأیید می کند که اتصال قرار است ارتقا یابد. هنگامی که این اتصال برقرار شد، به یک پروتکل باینری دوطرفه سوئیچ میکند، در این مرحله دادههای برنامه میتوانند ارسال شوند.
تنها کاری که پروتکل باید انجام دهد تا اتصال را باز نگه دارد ارسال چند بسته پینگ/پنگ است که به طرف مقابل می گوید که هنوز آنجا هستند. برای بستن اتصال، یک بسته ساده “close connection” ارسال می شود.
برخی از نمونه های Websocket
از بین بسیاری از کتابخانههای وب سوکت مختلف برای Node.js که در دسترس ما است، استفاده از آن را انتخاب کردم socket.io در سراسر این مقاله زیرا به نظر می رسد محبوب ترین است و به نظر من ساده ترین است. در حالی که هر کتابخانه API منحصر به فرد خود را دارد، از آنجایی که همه آنها ساخته شده اند، شباهت های زیادی نیز دارند روی در بالای همان پروتکل، بنابراین امیدوارم بتوانید کد زیر را به هر کتابخانه ای که می خواهید استفاده کنید ترجمه کنید.
برای سرور HTTP، از آن استفاده خواهم کرد بیان، که محبوب ترین سرور Node موجود است. به خاطر داشته باشید که می توانید از دشت نیز استفاده کنید http اگر به همه ویژگی های Express نیاز ندارید. اگرچه، از آنجایی که اکثر برنامه ها از Express استفاده می کنند، ما نیز از این استفاده خواهیم کرد.
توجه داشته باشید: در سراسر این مثالها، من بسیاری از کدهای دیگ بخار را حذف کردهام، بنابراین برخی از این کدها خارج از جعبه کار نمیکنند. در بیشتر موارد می توانید برای دریافت کد دیگ بخار به مثال اول مراجعه کنید.
برقراری ارتباط
برای اینکه ارتباط بین کلاینت و سرور برقرار شود، سرور باید دو کار را انجام دهد:
- برای مدیریت اتصالات وب سوکت به سرور HTTP متصل شوید
- سرو کنید
socket.io.js
کتابخانه مشتری به عنوان یک منبع ثابت
در کد زیر مشاهده می کنید که مورد (1) در حال انجام است روی خط 3 مورد (2) به صورت پیش فرض برای شما انجام می شود socket.io
کتابخانه و ارائه می شود روی مسیر /socket.io/socket.io.js
. به طور پیش فرض، تمام اتصالات و منابع وب سوکت در داخل سرویس ارائه می شود /socket.io
مسیر.
سرور
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
app.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
server.listen(8080);
مشتری باید دو کار را نیز انجام دهد:
- کتابخانه را از سرور بارگیری کنید
- زنگ زدن
.connect()
به آدرس سرور و مسیر وب سوکت
مشتری
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('/');
</script>
اگر مرورگر خود را به http://localhost:8080
و درخواستهای HTTP را در پشت صحنه با استفاده از ابزارهای توسعهدهنده مرورگر خود بررسی کنید، باید بتوانید اجرای دست دادن، از جمله درخواستهای GET و در نتیجه پاسخ پروتکلهای سوئیچینگ HTTP 101 را مشاهده کنید.
ارسال اطلاعات از سرور به کلاینت
باشه الان روی به برخی از قسمت های جالب تر در این مثال ما رایج ترین روش ارسال داده از سرور به مشتری را به شما نشان خواهیم داد. در این صورت، پیامی به کانالی ارسال می کنیم که می تواند مشترک شود و مشتری آن را دریافت کند. بنابراین، برای مثال، یک برنامه مشتری ممکن است در حال گوش دادن باشد روی کانال «اعلانها» که حاوی اعلانهایی درباره رویدادهای سراسر سیستم است، مانند زمانی که کاربر به اتاق چت میپیوندد.
در سرور این کار با صبر کردن برای برقراری اتصال جدید و سپس با فراخوانی انجام می شود socket.emit()
روشی برای ارسال پیام به همه مشتریان متصل
سرور
io.روی('connection', function(socket) {
socket.emit('announcements', { message: 'A new user has joined!' });
});
مشتری
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('/');
socket.روی('announcements', function(data) {
console.log('Got announcement:', data.message);
});
</script>
ارسال اطلاعات از کلاینت به سرور
اما وقتی میخواهیم دادهها را به روش دیگری، از کلاینت به سرور، ارسال کنیم، چه کار میکنیم؟ این بسیار شبیه به مثال آخر است، با استفاده از هر دو socket.emit()
و socket.روی()
مواد و روش ها.
سرور
io.روی('connection', function(socket) {
socket.روی('event', function(data) {
console.log('A client sent us this dumb message:', data.message);
});
});
مشتری
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('/');
socket.emit('event', { message: 'Hey, I have an important message!' });
</script>
شمارش کاربران متصل
این یک مثال خوب برای یادگیری است زیرا چند ویژگی دیگر را نشان می دهد socket.io
(مانند disconnect
رویداد)، پیاده سازی آن آسان است و برای بسیاری از برنامه های وب قابل اجرا است. ما از connection
و disconnect
رویدادها برای شمارش تعداد کاربران فعال روی سایت ما، و همه کاربران را با تعداد فعلی به روز می کنیم.
سرور
var numClients = 0;
io.روی('connection', function(socket) {
numClients++;
io.emit('stats', { numClients: numClients });
console.log('Connected clients:', numClients);
socket.روی('disconnect', function() {
numClients--;
io.emit('stats', { numClients: numClients });
console.log('Connected clients:', numClients);
});
});
مشتری
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('/');
socket.روی('stats', function(data) {
console.log('Connected clients:', data.numClients);
});
</script>
یک راه بسیار ساده تر برای ردیابی تعداد کاربران روی سرور فقط از این استفاده می کند:
var numClients = io.sockets.clients().length;
اما ظاهرا وجود دارند برخی مسائل در اطراف این موضوع، بنابراین ممکن است مجبور شوید تعداد مشتریان خود را پیگیری کنید.
اتاق ها و فضاهای نام
به احتمال زیاد با افزایش پیچیدگی برنامه شما، نیاز به سفارشی سازی بیشتری با سوکت های وب خود دارید، مانند ارسال پیام به یک کاربر خاص یا مجموعه ای از کاربران. یا شاید شما می خواهید به جداسازی دقیق منطق بین بخش های مختلف برنامه خود نیاز داشته باشید. اینجا جایی است که اتاق ها و فضاهای نام برای بازی وارد می شوند.
توجه داشته باشید: این ویژگی ها بخشی از پروتکل وب سوکت نیستند، بلکه اضافه شده اند روی بالا توسط socket.io
.
به صورت پیش فرض، socket.io
استفاده می کند root فضای نام (/
) برای ارسال و دریافت داده ها. به صورت برنامه نویسی می توانید از طریق این فضای نام دسترسی داشته باشید io.sockets
، اگرچه بسیاری از روش های آن میانبر دارند روی io
. بنابراین این دو فراخوانی معادل هستند:
io.sockets.emit('stats', { data: 'some data' });
io.emit('stats', { data: 'some data' });
برای ایجاد فضای نام خود، تنها کاری که باید انجام دهید این است:
var iosa = io.of('/rasanegar');
iosa.روی('connection', function(socket){
console.log('Connected to رسانگار namespace'):
});
iosa.emit('stats', { data: 'some data' });
همچنین، مشتری باید به طور واضح به فضای نام شما متصل شود:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('/rasanegar');
</script>
اکنون هر داده ای که در این فضای نام ارسال می شود از پیش فرض جدا خواهد بود /
فضای نام، صرف نظر از اینکه کدام کانال استفاده می شود.
حتی جلوتر بروید، در هر فضای نامی میتوانید به «اتاقها» بپیوندید و از آن خارج شوید. این اتاق ها لایه دیگری از جداسازی را فراهم می کنند روی بالای فضاهای نام، و از آنجایی که مشتری می تواند فقط به یک اتاق اضافه شود روی سمت سرور، آنها همچنین برخی از امنیت اضافی را فراهم می کنند. بنابراین اگر می خواهید مطمئن شوید که کاربران جاسوسی نمی کنند روی داده های خاص، می توانید از یک اتاق برای پنهان کردن آن استفاده کنید.
برای اضافه شدن به یک اتاق، باید .join()
آی تی:
io.روی('connection', function(socket){
socket.join('private-message-room');
});
سپس از آنجا میتوانید به همه افراد متعلق به اتاق داده شده پیام ارسال کنید:
io.to('private-message-room').emit('some event');
و در آخر تماس بگیرید .leave()
برای توقف دریافت پیام رویداد از یک اتاق:
socket.leave('private-message-room');
نتیجه
این تنها یک کتابخانه است که پروتکل websockets را پیاده سازی می کند، و تعداد بیشتری از آنها وجود دارد که همگی ویژگی ها و نقاط قوت منحصر به فرد خود را دارند. من توصیه می کنم برخی از موارد دیگر را امتحان کنید (مانند node-سوکت های وب) بنابراین شما نسبت به آنچه در خارج وجود دارد احساس می کنید.
تنها در عرض چند خط، می توانید برنامه های بسیار قدرتمندی ایجاد کنید، بنابراین من کنجکاو هستم که ببینم چه چیزی می توانید ایجاد کنید!
آیا ایده های جالبی دارید یا قبلاً برخی از برنامه ها را با استفاده از سوکت های وب ایجاد کرده اید؟ در نظرات به ما اطلاع دهید!
منتشر شده در 1403-01-29 02:17:03