Ssh चैट

हाय, हैब्र। कंसोल चैट एक शानदार चीज है, लेकिन फ्रंट-एंड के लिए, लेकिन क्या होगा यदि आप एक ही चाहते हैं, लेकिन बैकएंड के लिए। यदि हाँ, तो यह लेख आपके लिए है। लेकिन बैकेंड में अक्सर किस उपकरण का उपयोग किया जाता है? यह सही ssh है, इसलिए मैं sshchat का प्रतिनिधित्व करता हूं।


कैसा लगेगा


कहीं सर्वर पर, नोड पर कार्यक्रम कताई है।
जैसे ही कोई चैट से कनेक्ट करना चाहता है, वह प्रवेश करता है:


ssh server -p 8022 

उसके बाद, सिस्टम एक पासवर्ड पूछता है और एक विशेष फ़ाइल में पासवर्ड के साथ इसकी पुष्टि करता है। यदि पासवर्ड मेल खाता है, तो हम चैट से कनेक्ट करते हैं (उपयोगकर्ता को 100 पिछले संदेश मिलते हैं और बाकी सभी लोग देखते हैं कि वह जुड़ा हुआ है)।


फिर वह दूसरों के संदेश प्राप्त करता है, और खुद लिख सकता है।


संदेशों के साथ यहां और अधिक रोचक:


 @box{@color(red){Red text in box}} 

बॉक्स में लाल पाठ भेजें।


चलिए शुरू करते हैं


Ssh के साथ काम करने के लिए, हम https://www.npmjs.com/package/ssh2 का उपयोग करेंगे।
स्वरूपण के लिए हम चॉक और बॉक्सेन का उपयोग करते हैं।
इसलिए उन्हें स्थापित करें:


 npm i ssh2 chalk boxen 

अब कोड ही इस संदेश पार्सर ( GitHub ) के सबसे महत्वपूर्ण भागों में से एक है:


 //  chalk  boxen const chalk = require('chalk'); const boxen = require('boxen'); //         @ //   2           let methods = { color: function(args, text) { return chalk.keyword(args)(text); }, bold: function(args, text) { return chalk.bold(text); }, underline: function(args, text) { return chalk.underline(text); }, hex: function(args, text) { return chalk.hex(args)(text); }, box: function(args, text) { return boxen(text, { borderStyle: 'round', padding: 1, borderColor: 'blueBright' }); } }; //   function parseAndExecute(str) { let pos = 0; let stage = 0; let nS = ''; let bufs = ['', '', '', '']; let level = 0; while (pos < str.length) { let symbol = str[pos]; pos++; if (symbol == '\\' && '(){}@'.indexOf(str[pos]) !== -1) { bufs[stage] += str[pos]; pos++; continue; } if (stage == 0 && symbol == '@') { stage++; nS += bufs[0]; bufs[0] = ''; continue; } else if (stage >= 1) { if (symbol == '(') if (stage < 2) { stage = 2; } else { level++; } if (symbol == ')' && stage >= 2 && level > 0) level--; if (symbol == '{') if (stage != 3) { stage = 3; } else { level++; } if (symbol == '}') { if (level == 0) { bufs[3] += '}'; nS += methods[bufs[1]](bufs[2].slice(1, -1), parseAndExecute(bufs[3].slice(1, -1))); bufs = ['', '', '', '']; stage = 0; continue; } else { level--; } } } bufs[stage] += symbol; } return nS + bufs[0]; } module.exports.parseAndExecute = parseAndExecute; 

प्रारूपण ( GitHub ):


 const chalk = require('chalk'); const { parseAndExecute } = require('./parserExec') //  (    ) function getNick(nick) { let hash = 0; for (var i = 0; i < nick.length; i++) hash += nick.charCodeAt(i) - 32; return chalk.hsv((hash + 160) % 360, 90, 90)(chalk.bold(nick)); } module.exports.format = function(nick, message) { const nickSpace = '\r ' + ' '.repeat(nick.length); nick = getNick(nick) + ': '; message = message.replace(/\\n/gm, '\n'); //  \n   message = parseAndExecute(message) //  //       message = message .split('\n') .map((e, i) => '' + (i !== 0 ? nickSpace : '') + e) .join('\n'); return nick + message; }; 

सभी उपयोगकर्ताओं को संदेश भेजने और 100 संदेशों को सहेजने के तरीके ( GitHub ):


 let listeners = []; //   let cache = new Array(100).fill('') //  //     module.exports.addListener = write => listeners.push(write) - 1; module.exports.delListener = id => listeners.splice(id, 1); //   module.exports.broadcast = msg => { cache.shift() cache.push(msg) process.stdout.write(msg) listeners.forEach(wr => wr(msg)); } //   module.exports.getCache = ()=>cache.join('\r\033[1K') 

लॉबी, सर्वर निर्माण और प्राधिकरण ( GitHub ):


 const { Server } = require('ssh2'); const { readFileSync } = require('fs'); const hostKey = readFileSync('./ssh'); //   const users = JSON.parse(readFileSync('./users.json')); //  let connectionCallback = () => {}; module.exports.createServer = function createServer({ lobby }) { //   const server = new Server( { banner: lobby, //      hostKeys: [hostKey] }, function(client) { nick = ''; client .on('authentication', ctx => { //  if (ctx.method !== 'password') return ctx.reject(); if (ctx.password !== users[ctx.username]) ctx.reject(); nick = ctx.username; ctx.accept(); }) .on('ready', function() { connectionCallback(client, nick); }); } ); return server }; module.exports.setConnectCallback = callback => { //     connectionCallback = callback; }; 

विभिन्न तरीके ( GitHub ):


 const { createInterface } = require('readline'); module.exports.getStream = function(client, onStream, onEnd){ client //     .on('session', function(accept, reject) { accept() .on('pty', accept => accept & accept()) .on('shell', accept => onStream(accept())); }) .on('end', () => onEnd()); } //   module.exports.getCommunicator = function(stream, onMessage, onEnd){ let readline = createInterface({ //     input: stream, output: stream, prompt: '> ', historySize: 0, terminal: true }) readline.prompt() readline.on('close', ()=>{ radline = null; onEnd() stream.end() }) readline.on('line', (msg)=>{ stream.write('\033[s\033[1A\033[1K\r') onMessage(msg) readline.prompt() }) //     return msg=>{ stream.write('\033[1K\r' + msg) readline.prompt() } } 

अब गठबंधन ( GitHub ):


 const { createServer, setConnectCallback } = require('./lobby'); const { getStream, getCommunicator } = require('./utils'); const { addListener, delListener, broadcast, getCache } = require('./broadcaster'); const { format, getNick } = require('./format'); //    module.exports = function({ lobby = 'Hi' } = {}) { const server = createServer({ lobby }); setConnectCallback((client, nick) => { //   console.log('Client authenticated!'); let id = null; getStream( //   client, stream => { const write = getCommunicator( //   stream, msg => { if (msg == '') return; try { broadcast(format(nick, msg) + '\n'); //    ,    } catch (e) {} }, () => {} ); id = addListener(write); //   write('\033c' + getCache()); //   broadcast(getNick(nick) + ' connected\n'); //    }, () => { delListener(id); broadcast(getNick(nick) + ' disconnected\n') //    } ); }); server.listen(8022); }; 

और अंतिम चरण एक उदाहरण सर्वर है:


 const chat = require('.') chat({}) 

Users.json फ़ाइल भी उपयोगकर्ताओं और उनके पासवर्ड का वर्णन करती है।


निष्कर्ष


इस तरह आप ssh में सबसे आसान चैट नहीं लिख सकते।
ऐसी चैट के लिए, क्लाइंट को लिखने की आवश्यकता नहीं है, इसमें डिज़ाइन क्षमताएं हैं, और कोई भी इसे तैनात कर सकता है।


और क्या किया जा सकता है:


  • अपनी खुद की डिज़ाइन सुविधाएँ बनाने की क्षमता जोड़ें
  • मार्कडाउन समर्थन जोड़ें
  • बॉट समर्थन जोड़ें
  • पासवर्ड सुरक्षा बढ़ाएँ (हैश और नमक)

अंतिम रिपॉजिटरी

Source: https://habr.com/ru/post/hi466633/


All Articles