imported>Vix |
imported>Vix |
Строка 1: |
Строка 1: |
| process.nextTick(callback) - Гарантированно вызовет функцию callback в следующем цикле eventloop
| | '''ПОЭТАПНОЕ РУКОВОДСТВО ПО УСТАНОВКЕ И НАСТРОЙКЕ ТОНКОГО КЛИЕНТА НА ПЛАТФОРМЕ Linux Debian Squeeze ''' |
|
| |
|
| ==Серверный JavaScript==
| | *И так, собрав в кучу все имеющееся руководство по настройке "тонкого" клиента и перебрав всевозможные |
| [[Руководство NodeJS]]
| | варианты и решения, рассмотрим задачу по созданию универсального образа или точнее платформы, на которой |
| [[Node.js Virtual Machine (vm) Usage (перевод)]]
| | можно создавать те или иные решения, с применением безопасных технологий. |
| ===Node.JS Parent Process ID===
| | *Применительно к ситуации, создадим "тонкого" клиента, с возможностью обслуживания разделов жесткого диска, |
| Is it possible to get the parent process-id using Node.JS? I would like to detect if the parent is killed or fails in such a way that it cannot notify the child. If this happens, the parent process id of the child should become 1.
| | в частности с возможностью сохранения или восстановления образов партиций NTFS по сети. |
| | *'''Далее по порядку''': |
| | 1. Устанавливаем необходимые пакеты: |
| | apt-get install isc-dhcp-server tftpd-hpa ltsp-server nfs-common nfs-kernel-server |
|
| |
|
| This would be preferable to requiring the parent to periodically send a keep-alive signal and also preferable to running the ps command.
| | * рекомендуется после установки запустить программу aptitude и до установить требуемые пакеты, если есть такой запрос... |
| @Emmerman: I'm not sure what you mean. The parent runs require('child_process').spawn(process.argv[0], ['path_to_child.js']) in order to start the child. Then if it needs to talk to the child, it uses the stdin and stdout of the child. stderr is piped to a log. I am guessing the answer would be yes?
| | * при установке сервера tftpd-hpa он будет просить вас указать каталог где будет "платформа", согласитесь по умолчанию /srv/tftp или /opt/ltsp, все равно потом это будем менять.. |
|
| |
|
| *You can use pid-file. Something like that | | 2. '''Теперь настраиваем сервер DHCP''': |
| | *предположим что наша сеть такая: |
| | root@debvbox:~#cat /etc/network/interfaces |
|
| |
|
| <nowiki>var util = require('util'), | | # The loopback network interface |
| fs = require('fs'),
| | auto lo |
| pidfile = '/var/run/nodemaster.pid';
| | iface lo inet loopback |
| | |
| | # The primary network interface |
| | auto eth0 |
| | iface eth0 inet static |
| | address 10.10.5.1 |
| | netmask 255.255.255.0 |
| | network 10.10.5.0 |
| | broadcast 10.10.5.255 |
| | gateway 10.10.5.1 |
| | dns-nameservers 10.10.5.1 |
|
| |
|
| try {
| | *Исходя из этих данных настраиваем наш dhcp сервер: |
| var pid = fs.readFileSync(pidfile);
| | |
| //REPLACE with your signal or use another method to check process existence :)
| | root@debvbox:~# cat /etc/dhcp/dhcpd.conf |
| process.kill(pid, 'SIGUSR2');
| |
| util.puts('Master already running');
| |
| process.exit(1);
| |
| } catch (e) {
| |
| fs.writeFileSync(pidfile, process.pid.toString(), 'ascii');
| |
| }
| |
|
| |
|
| //run your childs here</nowiki>
| | ddns-update-style none; |
| | | |
| ==Библиотеки==
| | default-lease-time 259200; |
| ===Socket.IO===
| | max-lease-time 518400; |
| | | |
| Socket.IO is a Node.JS project that makes WebSockets and realtime possible in all browsers. It also enhances WebSockets by providing built-in multiplexing, horizontal scalability, automatic JSON encoding/decoding, and more.
| | authoritative; |
| | |
| '''Установка'''
| |
| | |
| npm install socket.io
| |
| | |
| '''Использование'''
| |
| | |
| First, require socket.io:
| |
| | |
| var io = require('socket.io');
| |
| | |
| Next, attach it to a HTTP/HTTPS server. If you're using the fantastic express web framework:
| |
| | |
| Express 3.x
| |
| | |
| <nowiki>var app = express() | |
| , server = require('http').createServer(app)
| |
| , io = io.listen(server);
| |
| | |
| server.listen(80);
| |
| | |
| io.sockets.on('connection', function (socket) {
| |
| socket.emit('news', { hello: 'world' });
| |
| socket.on('my other event', function (data) {
| |
| console.log(data);
| |
| });
| |
| });</nowiki>
| |
| | |
| | |
| Finally, load it from the client side code:
| |
| | |
| <nowiki><script src="/socket.io/socket.io.js"></script> | |
| <script>
| |
| var socket = io.connect('http://localhost');
| |
| socket.on('news', function (data) {
| |
| console.log(data);
| |
| socket.emit('my other event', { my: 'data' });
| |
| });
| |
| </script></nowiki>
| |
| | |
| For more thorough examples, look at the examples/ directory.
| |
| | |
| '''Примеры использования'''
| |
| | |
| Sending and receiving events.
| |
| | |
| Socket.IO allows you to emit and receive custom events. Besides connect, message and disconnect, you can emit custom events:
| |
| | |
| // note, io.listen(<port>) will create a http server for you
| |
| var io = require('socket.io').listen(80);
| |
| | |
| io.sockets.on('connection', function (socket) {
| |
| io.sockets.emit('this', { will: 'be received by everyone' });
| |
| | |
| socket.on('private message', function (from, msg) {
| |
| console.log('I received a private message by ', from, ' saying ', msg);
| |
| });
| |
| | |
| socket.on('disconnect', function () {
| |
| io.sockets.emit('user disconnected');
| |
| });
| |
| });
| |
| Storing data associated to a client
| |
| | |
| Sometimes it's necessary to store data associated with a client that's necessary for the duration of the session.
| |
| | |
| Server side
| |
| | |
| var io = require('socket.io').listen(80);
| |
| | |
| io.sockets.on('connection', function (socket) {
| |
| socket.on('set nickname', function (name) {
| |
| socket.set('nickname', name, function () { socket.emit('ready'); });
| |
| });
| |
| | |
| socket.on('msg', function () {
| |
| socket.get('nickname', function (err, name) {
| |
| console.log('Chat message by ', name);
| |
| });
| |
| });
| |
| });
| |
| Client side
| |
| | |
| <script>
| |
| var socket = io.connect('http://localhost');
| |
| | |
| socket.on('connect', function () {
| |
| socket.emit('set nickname', prompt('What is your nickname?'));
| |
| socket.on('ready', function () {
| |
| console.log('Connected !');
| |
| socket.emit('msg', prompt('What is your message?'));
| |
| });
| |
| });
| |
| </script>
| |
| Restricting yourself to a namespace
| |
| | |
| If you have control over all the messages and events emitted for a particular application, using the default / namespace works.
| |
| | |
| If you want to leverage 3rd-party code, or produce code to share with others, socket.io provides a way of namespacing a socket.
| |
| | |
| This has the benefit of multiplexing a single connection. Instead of socket.io using two WebSocket connections, it'll use one.
| |
| | |
| The following example defines a socket that listens on '/chat' and one for '/news':
| |
| | |
| Server side
| |
| | |
| var io = require('socket.io').listen(80);
| |
| | |
| var chat = io
| |
| .of('/chat')
| |
| .on('connection', function (socket) {
| |
| socket.emit('a message', { that: 'only', '/chat': 'will get' });
| |
| chat.emit('a message', { everyone: 'in', '/chat': 'will get' });
| |
| });
| |
| | |
| var news = io
| |
| .of('/news');
| |
| .on('connection', function (socket) {
| |
| socket.emit('item', { news: 'item' });
| |
| });
| |
| Client side:
| |
| | |
| <script>
| |
| var chat = io.connect('http://localhost/chat')
| |
| , news = io.connect('http://localhost/news');
| |
| | |
| chat.on('connect', function () {
| |
| chat.emit('hi!');
| |
| });
| |
| | |
| news.on('news', function () {
| |
| news.emit('woot');
| |
| });
| |
| </script>
| |
| Sending volatile messages.
| |
| | |
| Sometimes certain messages can be dropped. Let's say you have an app that shows realtime tweets for the keyword bieber.
| |
| | |
| If a certain client is not ready to receive messages (because of network slowness or other issues, or because he's connected through long polling and is in the middle of a request-response cycle), if he doesn't receive ALL the tweets related to bieber your application won't suffer.
| |
| | |
| In that case, you might want to send those messages as volatile messages.
| |
| | |
| Server side
| |
| | |
| var io = require('socket.io').listen(80);
| |
| | |
| io.sockets.on('connection', function (socket) {
| |
| var tweets = setInterval(function () {
| |
| getBieberTweet(function (tweet) {
| |
| socket.volatile.emit('bieber tweet', tweet);
| |
| });
| |
| }, 100);
| |
| | |
| socket.on('disconnect', function () {
| |
| clearInterval(tweets);
| |
| });
| |
| });
| |
| Client side
| |
| | |
| In the client side, messages are received the same way whether they're volatile or not.
| |
| | |
| Getting acknowledgements
| |
| | |
| Sometimes, you might want to get a callback when the client confirmed the message reception.
| |
| | |
| To do this, simply pass a function as the last parameter of .send or .emit. What's more, when you use .emit, the acknowledgement is done by you, which means you can also pass data along:
| |
| | |
| Server side
| |
| | |
| var io = require('socket.io').listen(80);
| |
| | |
| io.sockets.on('connection', function (socket) {
| |
| socket.on('ferret', function (name, fn) {
| |
| fn('woot');
| |
| });
| |
| });
| |
| Client side
| |
| | |
| <script>
| |
| var socket = io.connect(); // TIP: .connect with no args does auto-discovery
| |
| socket.on('connect', function () { // TIP: you can avoid listening on `connect` and listen on events directly too!
| |
| socket.emit('ferret', 'tobi', function (data) {
| |
| console.log(data); // data will be 'woot'
| |
| });
| |
| });
| |
| </script>
| |
| Broadcasting messages
| |
| | |
| To broadcast, simply add a broadcast flag to emit and send method calls. Broadcasting means sending a message to everyone else except for the socket that starts it.
| |
| | |
| Server side
| |
| | |
| var io = require('socket.io').listen(80);
| |
| | |
| io.sockets.on('connection', function (socket) {
| |
| socket.broadcast.emit('user connected');
| |
| socket.broadcast.json.send({ a: 'message' });
| |
| });
| |
| Rooms
| |
| | |
| Sometimes you want to put certain sockets in the same room, so that it's easy to broadcast to all of them together.
| |
| | |
| Think of this as built-in channels for sockets. Sockets join and leave rooms in each socket.
| |
| | |
| Server side
| |
| | |
| var io = require('socket.io').listen(80);
| |
| | |
| io.sockets.on('connection', function (socket) {
| |
| socket.join('justin bieber fans');
| |
| socket.broadcast.to('justin bieber fans').emit('new fan');
| |
| io.sockets.in('rammstein fans').emit('new non-fan');
| |
| });
| |
| Using it just as a cross-browser WebSocket
| |
| | |
| If you just want the WebSocket semantics, you can do that too. Simply leverage send and listen on the message event:
| |
| | |
| Server side
| |
| | |
| var io = require('socket.io').listen(80);
| |
| | |
| io.sockets.on('connection', function (socket) {
| |
| socket.on('message', function () { });
| |
| socket.on('disconnect', function () { });
| |
| });
| |
| Client side
| |
| | |
| <script>
| |
| var socket = io.connect('http://localhost/');
| |
| socket.on('connect', function () {
| |
| socket.send('hi');
| |
| | |
| socket.on('message', function (msg) {
| |
| // my msg
| |
| });
| |
| });
| |
| </script>
| |
| Changing configuration
| |
| | |
| Configuration in socket.io is TJ-style:
| |
| | |
| Server side
| |
| | |
| var io = require('socket.io').listen(80);
| |
| | |
| io.configure(function () {
| |
| io.set('transports', ['websocket', 'flashsocket', 'xhr-polling']);
| |
| });
| |
| | |
| io.configure('development', function () {
| |
| io.set('transports', ['websocket', 'xhr-polling']);
| |
| io.enable('log');
| |
| });
| |
| ====Перевод документации с оф. сайта====
| |
| '''Использование Node HTTP server'''
| |
| | |
| Установить npm install socket.io
| |
| | |
| '''''SERVER (APP.JS)'''''
| |
| | |
| <nowiki>var app = require('http').createServer(handler)
| |
| , io = require('socket.io').listen(app)
| |
| , fs = require('fs')
| |
| | | |
| app.listen(80); | | log-facility local7; |
| | #параметры настроек сети которые будет получать клиент.. |
| | shared-network debvbox { |
| | option nis-domain "debvbox"; |
| | option domain-name "debvbox"; |
| | option domain-name-servers 10.10.5.1; |
| | |
| | subnet 10.10.5.0 netmask 255.255.255.0 { |
| | #range 10.10.5.50 10.10.5.60; |
| | option routers 10.10.5.1; |
| | option subnet-mask 255.255.255.0; |
| | option broadcast-address 10.10.5.255; |
| | option time-offset -5; # Eastern Standard Time |
| | } |
| | | |
| function handler (req, res) { | | ########################MAC ADDDRESS ALL################# |
| fs.readFile(__dirname + '/index.html',
| | # здесь прописываем нашего будущего клиента, его мак адрес и.т.д. |
| function (err, data) {
| | host vclient { |
| if (err) {
| | option host-name "vclient"; |
| res.writeHead(500);
| | hardware ethernet 08:00:27:35:BA:D9; |
| return res.end('Error loading index.html');
| | fixed-address 10.10.5.65; |
| }
| | # этот параметр говорит какой образ загрузчика брать.. об этом дальше.. |
| res.writeHead(200);
| | filename "pxelinux.0"; |
| res.end(data);
| | } |
| });
| |
| }
| |
| | | |
| io.sockets.on('connection', function (socket) { | | * теперь прописываем какой интерфейс будет слушать сервер dhcp |
| socket.emit('news', { hello: 'world' });
| | root@debvbox:~# cat /etc/default/isc-dhcp-server |
| socket.on('my other event', function (data) {
| |
| console.log(data);
| |
| });
| |
| });</nowiki>
| |
|
| |
|
| '''''CLIENT (INDEX.HTML)'''''
| | # Defaults for dhcp initscript |
| | | # sourced by /etc/init.d/dhcp |
| <nowiki><script src="/socket.io/socket.io.js"></script> | | # installed at /etc/default/isc-dhcp-server by the maintainer scripts |
| <script> | | |
| var socket = io.connect('http://localhost');
| | # |
|
| | # This is a POSIX shell fragment |
| socket.on('news', function (data) {
| | # |
| console.log(data);
| | |
| socket.emit('my other event', { my: 'data' });
| | # On what interfaces should the DHCP server (dhcpd) serve DHCP requests? |
| });
| | # Separate multiple interfaces with spaces, e.g. "eth0 eth1". |
| </script></nowiki> | | INTERFACES="eth0" |
| | |
| '''Использование совместно с Express 3 web framework'''
| |
| | |
| Express 3 requires that you instantiate a `http.Server` to attach socket.io to first:
| |
| | |
| | |
| '''''SERVER (APP.JS)'''''
| |
| | |
| var app = require('express')() | |
| , server = require('http').createServer(app)
| |
| , io = require('socket.io').listen(server);
| |
| | | |
| server.listen(80); | | * в данном случае как видно это интерфейс - eth0 |
| | * теперь перезапускаем сервер dhcp и на этом настройка первого этапа закончена. |
| | root@debvbox:~# /etc/init.d/isc-dhcp-server restart |
| | | |
| app.get('/', function (req, res) { | | Stopping ISC DHCP server: dhcpd. |
| res.sendfile(__dirname + '/index.html');
| | Starting ISC DHCP server: dhcpd. |
| }); | |
|
| |
| io.sockets.on('connection', function (socket) {
| |
| socket.emit('news', { hello: 'world' });
| |
| socket.on('my other event', function (data) {
| |
| console.log(data);
| |
| });
| |
| });
| |
|
| |
|
| '''''CLIENT (INDEX.HTML)''''' | | 3. '''Настройка сервера TFTP - HPA''' |
| | * создаем каталог, где будет наша будущая система клиента в окружении chroot |
| | root@debvbox:~#mkdir /ltsp |
|
| |
|
| <nowiki><script src="/socket.io/socket.io.js"></script>
| | * прописываем для сервера tftp-hpa где будет наша "платформа" |
| <script> | | root@debvbox:~#cat /etc/default/tftpd-hpa |
| var socket = io.connect('http://localhost');
| |
|
| |
| socket.on('news', function (data) {
| |
| console.log(data);
| |
| socket.emit('my other event', { my: 'data' });
| |
| });
| |
| </script></nowiki>
| |
|
| |
|
| '''Использование совместно с Express web framework'''
| | # /etc/default/tftpd-hpa |
| | |
| | TFTP_USERNAME="tftp" |
| | TFTP_DIRECTORY="/ltsp/boot/" |
| | TFTP_ADDRESS="0.0.0.0:69" |
| | TFTP_OPTIONS="--secure" |
| | * перезапускаем сервер tftp-hpa |
| | root@debvbox:/etc# /etc/init.d/tftpd-hpa restart |
|
| |
|
| You can serve normal pages and AJAX requests with Express, and attach your socket.io server
| | Restarting HPA's tftpd: in.tftpd. |
|
| |
|
| For this example, simply run `npm install socket.io express`
| | Проверяем: |
| | netstat -lnp | grep :69 |
|
| |
|
| '''''SERVER (APP.JS)'''''
| | udp 0 0 0.0.0.0:69 0.0.0.0:* 16665/in.tftpd |
|
| |
|
| var app = require('express').createServer()
| |
| , io = require('socket.io').listen(app);
| |
| app.listen(80);
| |
| app.get('/', function (req, res) {
| |
| res.sendfile(__dirname + '/index.html');
| |
| });
| |
| io.sockets.on('connection', function (socket) {
| |
| socket.emit('news', { hello: 'world' });
| |
| socket.on('my other event', function (data) {
| |
| console.log(data);
| |
| });
| |
| });
| |
|
| |
|
| '''''CLIENT (INDEX.HTML)'''''
| |
|
| |
|
| <nowiki><script src="/socket.io/socket.io.js"></script>
| | 4. '''Настройка сервера LTSP''' |
| <script>
| | *Корневая файловая система, которую будут использовать клиенты, находится в каталоге /ltsp. Она должна быть доступна через NFS. Настраивается все это через конфиг /etc/exports |
| var socket = io.connect('http://localhost');
| | * прописываем настройки для сервера nfs-kernel, nfs-common |
| socket.on('news', function (data) {
| | root@debvbox:/etc# cat /etc/exports |
| console.log(data);
| |
| socket.emit('my other event', { my: 'data' });
| |
| });
| |
| </script></nowiki> | |
|
| |
|
| '''Отправка и прием событий.'''
| | # /etc/exports: the access control list for filesystems which may be exported |
| | # to NFS clients. See exports(5). |
| | # |
| | # Example for NFSv2 and NFSv3: |
| | # /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check) |
| | # |
| | # Example for NFSv4: |
| | # /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check) |
| | # /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check) |
| | ## первый каталог - это система и он в режиме только чтение... |
| | /ltsp/ *(ro,no_root_squash,async,no_subtree_check) |
| | ## второй - это домашняя папка пользователя, и он доступен уже на запись... |
| | /ltsp/home/user/ *(rw,no_root_squash,async,no_subtree_check) |
|
| |
|
| Socket.IO позволяет обрабатывать и отправлять произвольные события. Кроме `connect`, `message` and `disconnect`, можно создавать произвольные события:
| | Проверяем: |
| | showmount -e |
| | |
| | Export list for nzip: |
| | /home/ltsp/home/user/ * |
| | /home/ltsp/ * |
|
| |
|
| '''''SERVER'''''
| | * теперь создаем корневую систему для пользователя: |
| | root@debvbox:~# cd /ltsp |
| | root@debvbox:~# ltsp-build-client --arch i386 --dist squeeze --mirror http://ftp.ru.debian.org/debian/ squeeze main |
| | . |
| | . |
| | invoke-rc.d nfs-kernel-server reload |
| | info: LTSP client installation completed successfully |
|
| |
|
| // note, io.listen(<port>) will create a http server for you
| | * заходим в режиме chroot в каталог /ltsp |
| var io = require('socket.io').listen(80); | | root@debvbox:~# chroot /ltsp |
| io.sockets.on('connection', function (socket) { | | root@debvbox:~/# |
| io.sockets.emit('this', { will: 'be received by everyone'});
| |
| socket.on('private message', function (from, msg) {
| |
| console.log('I received a private message by ', from, ' saying ', msg);
| |
| });
| |
| socket.on('disconnect', function () {
| |
| io.sockets.emit('user disconnected');
| |
| });
| |
| });
| |
|
| |
|
| '''Прикрепление данных, ассоциированных с клиентом'''
| | * сразу добавляем пользователя который будет работать.. |
| | root@debvbox:~/# adduser user |
| | . |
| | . |
| | successfully |
|
| |
|
| Иногда необходимо хранить данные, ассоциированные с клиентом, что необходимо для продолжении (duration) сессии.
| | * до устанавливаем необходимые пакеты для работы клиентов.. |
| | root@debvbox:~/# apt-get install sudo ntfs-3g ntfsprogs |
|
| |
|
| '''''SERVER'''''
| | * выходим из режима chroot |
| <nowiki>var io = require('socket.io').listen(80); | | exit |
| io.sockets.on('connection', function (socket) { | | root@debvbox:~# |
| socket.on('set nickname', function (name) {
| |
| socket.set('nickname', name, function () {
| |
| socket.emit('ready');
| |
| });
| |
| });
| |
| socket.on('msg', function () {
| |
| socket.get('nickname', function (err, name) {
| |
| console.log('Chat message by ', name);
| |
| });
| |
| });
| |
| });
| |
| </nowiki>
| |
| '''''CLIENT'''''
| |
| <nowiki><script src="/socket.io/socket.io.js"></script>
| |
| <script>
| |
| var socket = io.connect('http://localhost');
| |
| socket.on('news', function (data) {
| |
| console.log(data);
| |
| socket.emit('my other event', { my: 'data' });
| |
| });
| |
| </script></nowiki>
| |
|
| |
|
| '''Оборачивание себя (своего кода) в namespace.'''
| | * прописываем права пользователя user в sudo и group в каталоге среды /ltsp/etc |
| | * теперь нам необходимо настроить загрузку нашего тонкого клиента, чтоб он мог по умолчанию через 15 секунд загружать систему с жесткого диска или выбрав нижнее меню, загрузить уже нашу среду и провести восстановление системы у себя с помощью ntfsclon |
|
| |
|
| Если вы контролируете все сообщения и события в коде, используйте namespace works по умолчанию (default namespace works)
| | root@debvbox:/ltsp# cat /ltsp/boot/pxelinux.cfg/default |
| Если вы хотите использовать сторонний код или предоставлять код другим, socket.io предоставляет возможность использования именованных сокетов (namespacing a socket.)
| |
|
| |
|
| Это полезно при мультиплексировании соединений. Вместо использования двух соединений WebSocket, будет использовано одно.
| | TIMEOUT 60 |
| | PROMPT 0 |
| | DEFAULT menu.c32 |
| | MENU TITLE BOOT_MENU |
| | MENU COLOR unsel 37;40 |
| | MENU COLOR sel 30;47 |
| | MENU COLOR border 37;40 |
| | MENU COLOR title 37;40 |
| | MENU COLOR hotkey 36;40 |
| | MENU COLOR tabmsg 36;40 |
| | MENU TABMSG Brought to you by Blue Light. |
| | MENU AUTOBOOT |
| | # |
| | # |
| | label WINDOWS |
| | localboot 0 |
| | # |
| | label SYSTEM_RECOVERY |
| | kernel vmlinuz |
| | APPEND ro initrd=initrd.img quiet root=/dev/nfs ip=dhcp boot=nfs nfsroot=10.10.5.1:/ltsp/ ramdisk=8192 |
|
| |
|
| ''''SERVER'''''
| | * для корректной работы загрузчика скопируем необходимую библиотеку.. |
| | | cp /ltsp/usr/lib/syslinux/menu.c32 /ltsp/boot/menu.c32 |
| <nowiki>var io = require('socket.io').listen(80);
| | |
| | | * перезапускаем сервер tftp-hpa |
| var chat = io
| | root@debvbox:/etc# /etc/init.d/tftpd-hpa restart |
| .of('/chat')
| |
| .on('connection', function (socket) {
| |
| socket.emit('a message', {
| |
| that: 'only'
| |
| , '/chat': 'will get'
| |
| });
| |
| chat.emit('a message', {
| |
| everyone: 'in'
| |
| , '/chat': 'will get'
| |
| });
| |
| });
| |
| | |
| var news = io
| |
| .of('/news')
| |
| .on('connection', function (socket) {
| |
| socket.emit('item', { news: 'item' });
| |
| });</nowiki>
| |
| '''''CLIENT'''''
| |
| | |
| <nowiki><script> | |
| var chat = io.connect('http://localhost/chat')
| |
| , news = io.connect('http://localhost/news');
| |
|
| |
| chat.on('connect', function () {
| |
| chat.emit('hi!');
| |
| });
| |
|
| |
| news.on('news', function () {
| |
| news.emit('woot');
| |
| });
| |
| </script></nowiki>
| |
| | |
| '''Отправка летучих (volatile) сообщений.'''
| |
| | |
| Иногда некоторые сообщения могут быть удалены (отброшены). Скажем, у вас есть приложение, которое показывает в реальном времени количество твитов по ключевому слову Бибер.
| |
| | |
| Если определенный клиент не готов к приему сообщений (из-за медлительности сети или других вопросов, или потому, что он связан через длинные голосования и находится в середине запрос-ответ цикла), если он не получит всех твитов, связанных с Бибер, то ваша заявка не будет страдать.
| |
| | |
| В этом случае, вы можете отправить эти сообщения, как летучие сообщений.
| |
| | |
| '''''SERVER'''''
| |
| | |
| <nowiki>var io = require('socket.io').listen(80);
| |
| | |
| io.sockets.on('connection', function (socket) {
| |
| var tweets = setInterval(function () {
| |
| getBieberTweet(function (tweet) {
| |
| socket.volatile.emit('bieber tweet', tweet);
| |
| });
| |
| }, 100);
| |
| | |
| socket.on('disconnect', function () {
| |
| clearInterval(tweets);
| |
| });
| |
| });</nowiki>
| |
| | |
| '''Отправка и получение данных (подтверждения)'''
| |
| | |
| Иногда, вы можете получить обратный вызов, когда клиент подтвердил прием сообщения.
| |
| | |
| Чтобы сделать это, просто передать функцию в качестве последнего параметра `.send` или `.emit`. Более того, когда вы используете `.emit`, подтверждение было сделано вами, значит, вы также можете продолжить передавать данные.
| |
| | |
| '''''SERVER'''''
| |
| | |
| <nowiki>var io = require('socket.io').listen(80);
| |
| | |
| io.sockets.on('connection', function (socket) {
| |
| socket.on('ferret', function (name, fn) {
| |
| fn('woot');
| |
| });
| |
| });</nowiki>
| |
| | |
| '''''CLIENT'''''
| |
| | |
| <nowiki><script>
| |
| var socket = io.connect(); // TIP: .connect with no args does auto-discovery
| |
| socket.on('connect', function () { // TIP: you can avoid listening on `connect` and listen on events directly too!
| |
| socket.emit('ferret', 'tobi', function (data) {
| |
| console.log(data); // data will be 'woot'
| |
| });
| |
| });
| |
| </script></nowiki>
| |
| | |
| '''Broadcasting messages.'''
| |
| | |
| To broadcast, simply add a `broadcast` flag to `emit` and `send` method calls. Broadcasting means sending a message to everyone else except for the socket that starts it.
| |
| | |
| '''''SERVER'''''
| |
| | |
| <nowiki>var io = require('socket.io').listen(80);
| |
| | |
| io.sockets.on('connection', function (socket) {
| |
| socket.broadcast.emit('user connected');
| |
| });</nowiki>
| |
| | |
| '''Using it just as a cross-browser WebSocket.'''
| |
| | |
| If you just want the WebSocket semantics, you can do that too. Simply leverage `send` and listen on the `message` event:
| |
| | |
| '''''SERVER'''''
| |
| | |
| <nowiki>var io = require('socket.io').listen(80);
| |
| | |
| io.sockets.on('connection', function (socket) {
| |
| socket.on('message', function () { });
| |
| socket.on('disconnect', function () { });
| |
| });</nowiki>
| |
| | |
| '''''CLIENT'''''
| |
| | |
| <nowiki><script>
| |
| var socket = io.connect('http://localhost/');
| |
| socket.on('connect', function () {
| |
| socket.send('hi');
| |
| | |
| socket.on('message', function (msg) {
| |
| // my msg
| |
| });
| |
| });
| |
| </script></nowiki>
| |
| | |
| ====Примеры кода====
| |
| | |
| http://kuroikaze85.wordpress.com/2010/06/15/socket-io-node-js-game-making/
| |
| [http://www.ibm.com/developerworks/ru/library/cl-nodejscloud/ Применение Node.js в качестве полной среды разработки для облачных решений]
| |
| <hr>
| |
| ==Официальная документция==
| |
| | |
| | |
| * [http://nodejs.org/api/modules.html nodejs.org]
| |
| | |
| * [http://nodeguide.ru/doc/ Руководства по Node.js от Felix’а]
| |
| | |
| * [http://nodebeginner.ru/ Руководства по Node.js упрощенное...] | |
| | |
| * [http://vremenno.net/js/node-js-for-beginners/ примеры начинающим]
| |
| | |
| ==АКСИОМЫ NODE.JS==
| |
| Callback-driven парадигма
| |
| | |
| Неблокирующая функция принимает callback последним аргументом:
| |
| | |
| <nowiki>function asuncFunction(arg1,arg2,...,argN, callback){
| |
| | |
| }</nowiki>
| |
| | |
| Callback принимает ошибку первым аргументом, остальные результат:
| |
| | |
| <nowiki>function callback(error, result1,result2,...resultN){ | |
| | |
| }</nowiki>
| |
| | |
| ==Кластер==
| |
| [[Кластер на основе NodeJS]] -
| |
| | |
| ==Примеры архитектуры==
| |
| [[Tactoom.com изнутри — социальная блог-платформа на NodeJS/NoSQL]]
| |
| | |
| ==Обработка форм и визуализации через NodeJs==
| |
| | |
| [http://nodejs.ru/665]http://nodejs.ru/665
| |
| | |
| [http://habrahabr.ru/post/138629/]http://habrahabr.ru/post/138629/
| |
| | |
| [http://nodeguide.ru/doc/dailyjs-nodepad/node-tutorial-7/]http://nodeguide.ru/doc/dailyjs-nodepad/node-tutorial-7/
| |
| | |
| [http://habrahabr.ru/post/147571/]http://habrahabr.ru/post/147571/
| |
| | |
| [http://www.pvsm.ru/node-js/12212]http://www.pvsm.ru/node-js/12212
| |
| | |
| [http://www.pixelcom.crimea.ua/rukovodstvo-po-html5-canvas.html]http://www.pixelcom.crimea.ua/rukovodstvo-po-html5-canvas.html
| |
| | |
| :[[Установка node.js в Debian]]
| |
|
| |
|
| *Express: веб-фреймворк для Node.js. Руководство пользователя
| | Restarting HPA's tftpd: in.tftpd. |
| [http://jsman.ru/express/]http://jsman.ru/express/
| | * пробуем загрузится "тонким" клиентом |
|
| |
|
| * Руководство для начинающих | | * [https://habrahabr.ru/post/277783/ полезное...] |
| [http://vremenno.net/js/node-js-for-beginners/]http://vremenno.net/js/node-js-for-beginners/ | |
| | |
| *Скелет приложения на Node.js с использованием express, mongoose, backbone.js, socket.io
| |
| [http://kulakowka.com/tag/express/]http://kulakowka.com/tag/express/
| |
| | |
| *Русскоязычное сообщество Node.js
| |
| [http://forum.nodejs.ru/index.php?topic=130.0]http://forum.nodejs.ru/index.php?topic=130.0
| |
| | |
| *[http://www.pvsm.ru/node-js/16286 Установка node.js на VPS]
| |
| | |
| ==Технологии спутники==
| |
| Перечень модулей для Node.js https://github.com/joyent/node/wiki/modules
| |
| ===Node-sync===
| |
| [[Node-sync_—_псевдо-синхронное_программирование_на_nodejs_с_использованием_fibers]]
| |
| ===socket.io===
| |
| * [http://socket.io/ socket.io] [[socket.io документация]]
| |
| * [http://blog.denivip.ru/index.php/2012/11/разработка-высокопроизводительных-с/ webSocketServer ru]
| |
| | |
| ===Express===
| |
| *[http://jsman.ru/express/#quickstart Express: веб-фреймворк для Node.js. Руководство пользователя][[Express: веб-фреймворк для Node.js. Руководство пользователя|Сохраненная копия]]
| |
| | |
| ==Отладка и сборка==
| |
| *[http://nodejs.ru/324 Отладчик ndb]
| |
| *[http://jsman.ru/2012/08/24/browserify.html Browserify - cобираем JS-проект]
| |
| *[[JavaScript Strict Mode]]
| |
| | |
| ==Примеры кода==
| |
| ===Цепочка вызывающих себя через callback'и функций с передачей данных следующей функции (обработка ошибок в одном месте, массив функций в качестве параметра)===
| |
| | |
| С использованием async это пишется так:
| |
| | |
| <nowiki>var async = require('async');
| |
| | |
| async.waterfall([
| |
| function(callback){
| |
| setTimeout(function() {
| |
| console.log('f1 done');
| |
| callback(null, 'data from f1');
| |
| }, 100);
| |
| },
| |
| function(data, callback){
| |
| // работа с data
| |
| // или расширение цепочки через функцию f3, которая по окончании работы вызовет callback
| |
| // f3(callback);
| |
| console.log('f2 done');
| |
| callback(null, 'done');
| |
| }
| |
| ], function (err, result) {
| |
| // result now equals 'done'
| |
| if (err) {
| |
| // единое место для отлова ошибок
| |
| }
| |
| console.log(result);
| |
| });</nowiki>
| |
| | |
| == Дополнительные возможности nodejs ==
| |
| | |
| * [http://docs.nodejitsu.com/articles/child-processes/how-to-spawn-a-child-process вызов сторонних команд]
| |
| | |
| == Полезные ресурсы ==
| |
| * [http://nodejs.org/download/ node.js]
| |
| * [http://nodejs.ru/707 коротко о всех командах node.js]
| |
| | |
| * [http://www.askdev.ru/blog/nodejs/54/Отличное-руководство-для-начинающих-по-Node-js/ полезное на старте.]
| |
| * [http://vremenno.net/js/node-js-for-beginners/ примеры кода]
| |
| * [http://habrahabr.ru/post/102717/ примеры с Хабра]
| |
| * [http://drumcoder.co.uk/blog/2011/jan/10/nodejs-phone-book/ пример работы с postgresql]
| |
| | |
| * [http://jade-lang.com/ .. не все понял но здорово.."шаблнизатор"]
| |
| * [https://github.com/visionmedia/jade#readme описание шаблонизатора..]
| |
| * [http://www.mongodb.org/ база данных под node.js]
| |
| * [http://www.pvsm.ru/web-razrabotka/2198/print/ то что нужно знать!]
| |
| * [http://www.slideshare.net/yurabogdanov/nodejs-8223169 профи советы]
| |
| * [http://habrahabr.ru/post/130345/ чужой опыт...]
| |
| * [http://habrahabr.ru/post/138071/ еще чужой опыт...]
| |
| <hr>
| |
| ''''''Отладка в Node.Js''''''
| |
| * [https://github.com/ajaxorg/cloud9 среда разработки для node.js]
| |
| * [https://github.com/dannycoates/node-inspector отлачик для node.js]
| |
| * [http://habrahabr.ru/post/114825/ использование node-inspector]
| |
| * [http://nodejs.ru/doc/v0.4.x/debugger.html встроенный отладчик]
| |
| * [http://nodejs.ru/324 Ndb отладка в node]
| |
| <hr>
| |
| * [[Node.js debian init.script]]
| |
| <hr> | | <hr> |
| '''''@модули для node.js'''''
| | * [https://habr.com/ru/company/serverclub/blog/250549/ Загрузочный сервер — как загрузочная флешка, только сервер и по сети] |
| * [http://thechangelog.com/stylus-expressive-robust-feature-rich-css-language/ stylus - работа со стилями через nod.js] | |