


1. Verwenden Sie Node, um einen statischen Server zu erstellen
Dies ist der zugrunde liegende Unterstützungsteil dieses Projekts. Wird verwendet, um den Zugriff auf statische Ressourcendateien wie HTML, CSS, GIF, JPG, PNG, Javascript, JSON, Nur-Text usw. zu unterstützen. Hier gibt es eine MIME-Typ-Dateizuordnung.
mime.js
/** * mime类型的 map * @ author Cheng Liufeng * @ date 2014/8/30 * 当请求静态服务器文件的类型 html, css, gif, jpg, png, javascript, json, plain text, 我们会在此文件进行映射 */ exports.types = { "css": "text/css", "gif": "image/gif", "html": "text/html", "ico": "image/x-icon", "jpeg": "image/jpeg", "jpg": "image/jpeg", "js": "text/javascript", "json": "application/json", "pdf": "application/pdf", "png": "image/png", "svg": "image/svg+xml", "swf": "application/x-shockwave-flash", "tiff": "image/tiff", "txt": "text/plain", "wav": "audio/x-wav", "wma": "audio/x-ms-wma", "wmv": "video/x-ms-wmv", "xml": "text/xml" };
Hier erkläre ich zunächst den Vorgang von der Eingabe der URL bis zum Erscheinen der Seite. Wenn der Benutzer eine URL in die Adressleiste des Browsers eingibt.
Als nächstes wird eine Reihe von Prozessen stattfinden. Die erste ist die DNS-Auflösung, die den Domänennamen in die entsprechende IP-Adresse umwandelt. Anschließend stellen der Browser und der Remote-Webserver über eine TCP-Drei-Wege-Handshake-Aushandlung eine TCP/IP-Verbindung her. Der Handshake umfasst eine Synchronisationsnachricht, eine Synchronisationsantwortnachricht und eine Antwortnachricht. Diese drei Nachrichten werden zwischen dem Browser und dem Server weitergeleitet. Bei diesem Handshake versucht der Client zunächst, eine Kommunikation herzustellen, dann antwortet der Server und akzeptiert die Anfrage des Clients, und schließlich sendet der Client eine Nachricht, dass die Anfrage angenommen wurde. Sobald die TCP/IP-Verbindung hergestellt ist, sendet der Browser über die Verbindung eine HTTP-GET-Anfrage an den Remote-Server.
Der Remote-Server findet die Ressource und gibt sie mithilfe einer HTTP-Antwort zurück. Ein HTTP-Antwortstatus von 200 zeigt eine korrekte Antwort an. Zu diesem Zeitpunkt stellt der Webserver Ressourcendienste bereit und der Client beginnt mit dem Herunterladen von Ressourcen. Zu den heruntergeladenen Ressourcen gehören HTML-Dateien, CSS-Dateien, Javascript-Dateien und Bilddateien. Beginnen Sie dann mit dem Aufbau eines Rendering-Baums und eines DOM-Baums, wobei es zu CSS-Blockierungen und JS-Blockierungen kommt. Daher erfordert die unterste Ebene eine statische Serverunterstützung. Hier erstelle ich nativ einen statischen Server, ohne das Express-Framework zu verwenden.
Tatsächlich ist der Prozess jeder Ressourcendateianforderung eine GET-Anfrage. Als Nächstes erkläre ich den serverseitigen Verarbeitungsprozess, der der GET-Anfrage vom Client entspricht (browserseitig oder mithilfe der Curl-Methode unter Linux). Nachdem eine Get-Anfrage an den Server gesendet wurde, kann der Server dem Pfad einer Ressourcendatei entsprechend der GET-Anfrage entsprechen. Nachdem wir diesen Pfad kennen, können wir das Lesen und Schreiben von Dateien verwenden, um die Ressourcen unter dem angegebenen Pfad abzurufen und sie dann an den Client zurückzugeben.
Wir wissen, dass die APIs zum Lesen und Schreiben von Dateien in Node readFile und readFileSync umfassen. Eine bessere Möglichkeit besteht jedoch darin, einen Stream zum Lesen von Dateien zu verwenden. Der Vorteil der Verwendung eines Streams besteht darin, dass Caching und GZIP-Komprimierung verwendet werden können.
OK, wie implementiert man Caching? Wenn der Client zum ersten Mal eine Anfrage stellt, liest der Server normalerweise die Ressourcendatei und gibt sie an den Client zurück. Wenn Sie jedoch dieselbe Datei ein zweites Mal anfordern, müssen Sie dennoch eine Anfrage an den Server senden. Der Server bestimmt anhand von Ablaufdaten, Cache-Kontrolle, If-Modified-Since und anderen HTTP-Header-Informationen, ob diese Ressource zwischengespeichert wurde. Wenn ein Cache vorhanden ist, greift der Server nicht erneut auf den tatsächlichen Pfad der Ressourcendatei zu. Zwischengespeicherte Ressourcen direkt zurückgeben.
server.js
/** * 聊天室服务端 * 功能:实现了Node版的静态服务器 * 实现了缓存,gzip压缩等 * @ author Cheng Liufeng * @ date 2014/8/30 */ // 设置端口号 var PORT = 3000; // 引入模块 var http = require('http'); var url = require('url'); var fs = require('fs'); var path = require('path'); var zlib = require('zlib'); // 引入文件 var mime = require('./mime').types; var config = require('./config'); var chatServer = require('./utils/chat_server'); var server = http.createServer(function (req, res) { res.setHeader("Server","Node/V8"); // 获取文件路径 var pathName = url.parse(req.url).pathname; if(pathName.slice(-1) === "/"){ pathName = pathName + "index.html"; //默认取当前默认下的index.html } // 安全处理(当使用Linux 的 curl命令访问时,存在安全隐患) var realPath = path.join("client", path.normalize(pathName.replace(/\.\./g, ""))); // 检查文件路径是否存在 path.exists(realPath, function(exists) { // 当文件不存在时的情况, 输出一个404错误 if (!exists) { res.writeHead(404, "Not Found", {'Content-Type': 'text/plain'}); res.write("The request url" + pathName +" is not found!"); res.end(); } else { // 当文件存在时的处理逻辑 fs.stat(realPath, function(err, stat) { // 获取文件扩展名 var ext = path.extname(realPath); ext = ext ? ext.slice(1) : "unknown"; var contentType = mime[ext] || "text/plain"; // 设置 Content-Type res.setHeader("Content-Type", contentType); var lastModified = stat.mtime.toUTCString(); var ifModifiedSince = "If-Modified-Since".toLowerCase(); res.setHeader("Last-Modified", lastModified); if (ext.match(config.Expires.fileMatch)) { var expires = new Date(); expires.setTime(expires.getTime() + config.Expires.maxAge * 1000); res.setHeader("Expires", expires.toUTCString()); res.setHeader("Cache-Control", "max-age=" + config.Expires.maxAge); } if (req.headers[ifModifiedSince] && lastModified == req.headers[ifModifiedSince]) { res.writeHead(304, "Not Modified"); res.end(); } else { // 使用流的方式去读取文件 var raw = fs.createReadStream(realPath); var acceptEncoding = req.headers['accept-encoding'] || ""; var matched = ext.match(config.Compress.match); if (matched && acceptEncoding.match(/\bgzip\b/)) { res.writeHead(200, "Ok", {'Content-Encoding': 'gzip'}); raw.pipe(zlib.createGzip()).pipe(res); } else if (matched && acceptEncoding.match(/\bdeflate\b/)) { res.writeHead(200, "Ok", {'Content-Encoding': 'deflate'}); raw.pipe(zlib.createDeflate()).pipe(res); } else { res.writeHead(200, "Ok"); raw.pipe(res); }
//Das Folgende ist eine gängige Methode zum Lesen von Dateien, nicht empfohlen
// fs.readFile(realPath, "binary", function(err, data) { // if(err) { // // file exists, but have some error while read // res.writeHead(500, {'Content-Type': 'text/plain'}); // res.end(err); // } else { // // file exists, can success return // res.writeHead(200, {'Content-Type': contentType}); // res.write(data, "binary"); // res.end(); // } // }); } }); } }); });
//Port 3000 abhören
server.listen(PORT, function() { console.log("Server is listening on port " + PORT + "!"); });
// Lassen Sie den Socket.io-Server und den http-Server einen Port gemeinsam nutzen
chatServer.listen(server);
Zweitens verwendet der Server WebSocket, um den Chatroom-Server zu erstellen
Warum Websocket verwenden?
Wir wissen, dass Mainstream-Chatrooms immer noch Ajax verwenden, um die Kommunikation zwischen dem Client und dem Server zu realisieren. Es wird ein Polling-Mechanismus verwendet. Das sogenannte Polling bedeutet, dass der Client von Zeit zu Zeit eine Anfrage an den Server sendet, um zu sehen, ob neue Chat-Daten auf dem Server vorhanden sind. Wenn neue Daten vorhanden sind, werden diese an den Client zurückgegeben.
Websocket ist völlig anders. Websocket basiert auf langen Links. Das heißt, sobald eine Verbindung zwischen dem Client und dem Server hergestellt wurde, bleibt die Verbindung immer bestehen. Es handelt sich um eine Vollduplex-Kommunikation. Der Mechanismus ähnelt derzeit in gewisser Weise dem Publish-Subscribe-Modell. Der Client abonniert einige Ereignisse und sobald neue Daten auf dem Server erscheinen, werden diese aktiv an den Client übertragen.
Websocket verwendet das WS-Protokoll, nicht das http-Protokoll oder das https-Protokoll. Ein weiterer Vorteil der Verwendung von WebSocket besteht darin, dass dadurch ein großer Teil des Datenverkehrs reduziert werden kann. Zu Beginn des Artikels habe ich den traditionellen einmaligen Ressourcenanforderungsprozess vorgestellt, der ein Drei-Wege-Handshake-Protokoll erfordert und jeder Anforderungsheader relativ viel Platz einnimmt, was viel Verkehr verbraucht. Die Header, die in Websocket für die Kommunikation untereinander verwendet werden, sind sehr klein – nur etwa 2 Bytes.
/** * 聊天服务。 */ var socketio = require('socket.io'); var io; var guestNumber = 1; //初始用户名编号 var nickNames = {}; // 昵称列表 var namesUsed = []; //使用过的用户名 var currentRoom = {}; //当前聊天室 function assignGuestName(socket, guestNumber, nickNames, namesUsed) { var name = 'Guest' + guestNumber; nickNames[socket.id] = name; socket.emit('nameResult', { success: true, name: name }); namesUsed.push(name); return guestNumber + 1; } function joinRoom(socket, room) { socket.join(room); currentRoom[socket.id] = room; socket.emit('joinResult', {room: room}); socket.broadcast.to(room).emit('message', { text: nickNames[socket.id] + 'has joined ' + room + '.' }); } function handleMessageBroadcasting(socket) { socket.on('message', function(message) { socket.broadcast.to(message.room).emit('message', { text: nickNames[socket.id] + ':' + message.text }); }); } exports.listen = function(server) { io = socketio.listen(server); io.set('log level', 1); // 定义每个用户的连接处理 io.sockets.on('connection', function(socket) { // 分配一个用户名 guestNumber = assignGuestName(socket, guestNumber, nickNames, namesUsed); // 将用户加入聊天室Lobby里 joinRoom(socket, 'Lobby'); //处理聊天信息 handleMessageBroadcasting(socket, nickNames); //handleNameChangeAttempts(socket, nickNames, namesUsed); //handleRoomJoining(socket); //handleClientDisconnection(socket, nickNames, namesUsed); }); };
三,利用Angular搭建聊天室客户端
为什么使用Angular?
作为一款前端MVC框架,Angular.js无疑是引人注目的。模块化,双向数据绑定,指令系统,依赖注入。而且Angular内置jquerylite,这让熟悉jQuery语法的同学很容易上手。
当然,个人认为, angular在构建一个单页应用和crud项目方面有很大的优势。 我们这个聊天室就是基于SPA(single page application)的目的。
index.html
<!DOCTYPE html> <html ng-app="chatApp"> <head> <meta name="viewport" content="width=device-width, user-scalable=no"> </head> <body ng-controller="InitCtrl"> <div ng-view></div> <script src="lib/angular.js"></script> <script src="lib/angular-route.js"></script> <script src="lib/socket.io.js"></script> <script src="app.js"></script> <script src="controllers/InitCtrl.js"></script> </body> </html>
怎样构建一个单页应用?单页应用的原理?
先谈谈单页应用的原理。所谓单页,并不是整个页面无刷新。当你审查一下google chrome的console控制台的时候,你会发现,angular内部还是采用了ajax去异步请求资源。所以只是局部刷新。但是这种方式相对于以前的DOM节点的删除和修改已经有很大的进步了。
构建单页应用,我们需要借助于angular-route.js。这个angular子项目可以帮助我们定义路由和对应的逻辑处理控制器。利用它,我们可以实现一个单页应用。
app.js
/** * 客户端(目前只支持浏览器,将来会扩展到移动端)程序入口文件 * 创建一个模块,并且命名为chatApp * 配置路由,实现单页应用(single page application) */ var chatApp = angular.module("chatApp", ['ngRoute']); // 路由配置 chatApp.config(function($routeProvider) { $routeProvider.when('/', { templateUrl : 'views/init.html', controller: 'InitCtrl' }) .when('/init', { templateUrl : 'views/init.html', controller: 'InitCtrl' }); });
客户端聊天界面的代码逻辑如下
InitCtrl.js
/** * # InitCtrl */ angular.module('chatApp').controller('InitCtrl', function($scope) { var socket = io.connect('http://127.0.0.1:3000'); socket.on('nameResult', function(result) { var message; if (result.success) { message = 'you are now known as ' + result.name + '.'; console.log('message=', message); document.getElementById('guestname').innerHTML = message; } else { message = result.message; } }); socket.on('joinResult', function(result) { document.getElementById('room').innerHTML = result.room; }); $scope.sendMessage = function() { var message = { room: 'Lobby', text: document.getElementById('user_input').value }; socket.emit('message', message); }; socket.on('message', function(message) { var p = document.createElement('p'); p.innerHTML = message.text; document.getElementById('message').appendChild(p); }); });
基于node.js和socket.io搭建多人聊天室
刚学node.js,想着做点东西练练手。网上的东西多而杂,走了不少弯路,花了一天时间在调代码上。参考网上的一篇文章,重写了部分代码,原来的是基于基于node-websocket-server框架的,我没用框架,单单是socket.io。
一、基本功能
1、用户随意输入一个昵称即可登录
2、登录成功后
1) 对正在登录用户来说,罗列所有在线用户列表,罗列最近的历史聊天记录
2) 对已登录的用户来说,通知有新用户进入房间,更新在线用户列表
3、退出登录
1)支持直接退出
2) 当有用户退出,其他所有在线用户会收到信息,通知又用户退出房间,同时更新在线用户列表
4、聊天
1) 聊天就是广播,把信息广播给所有连接在线的用户
5、一些出错处理
1) 暂时简单处理了系统逻辑错误、网络出错等特殊情况的出错提示
问题:功能不完善,有bug(退出后,新用户重新登录,还是原来的用户) 。抽空完善吧
二、技术介绍
socket.io(官网:http://socket.io/)是一个跨平台,多种连接方式自动切换,做即时通讯方面的开发很方便,而且能和expressjs提供的传统请求方式很好的结合,即可以在同一个域名,同一个端口提供两种连接方式:request/response, websocket(flashsocket,ajax…)。
这篇文章对socket.io的使用做了详细介绍:http://www.jb51.net/article/71361.htm
《用node.js和Websocket做个多人聊天室吧》http://www.html5china.com/HTML5features/WebSocket/20111206_3096.html
三、注意事项
(1)客户端这样引用socket.io.js:
<script src="/socket.io/socket.io.js"></script>
可能会加载失败(我在这里耗了不少时间)
可以改为:
<script src="http://ip:port/socket.io/socket.io.js"></script>
(对应服务器的ip地址和端口号,比如说localhost和80端口)
(2)实现广播的时候,参考官网的写法,竟然不起作用,如:
var io = require('socket.io').listen(80); io.sockets.on('connection', function (socket) { socket.broadcast.emit('user connected'); socket.broadcast.json.send({ a: 'message' }); });
后来看了这个:http://stackoverflow.com/questions/7352164/update-all-clients-using-socket-io
改为以下才起作用:
io.sockets.emit('users_count', clients);
四、效果图
五、源码下载
ps:
1、在命令行运行
node main.js
然后在浏览器中打开index.html,如果浏览器(ff、Chrome)不支持,请升级到支持WebSocket的版本.
2、推荐node.js的IDE WebStorm
以上内容就是本文基于Angular和Nodejs搭建聊天室及多人聊天室的实现,希望大家喜欢。

JavaScript ist das Herzstück moderner Websites, da es die Interaktivität und Dynamik von Webseiten verbessert. 1) Es ermöglicht die Änderung von Inhalten, ohne die Seite zu aktualisieren, 2) Webseiten durch DOMAPI zu manipulieren, 3) Komplexe interaktive Effekte wie Animation und Drag & Drop, 4) die Leistung und Best Practices optimieren, um die Benutzererfahrung zu verbessern.

C und JavaScript erreichen die Interoperabilität durch WebAssembly. 1) C -Code wird in das WebAssembly -Modul zusammengestellt und in die JavaScript -Umgebung eingeführt, um die Rechenleistung zu verbessern. 2) In der Spieleentwicklung kümmert sich C über Physik -Engines und Grafikwiedergabe, und JavaScript ist für die Spiellogik und die Benutzeroberfläche verantwortlich.

JavaScript wird in Websites, mobilen Anwendungen, Desktop-Anwendungen und serverseitigen Programmierungen häufig verwendet. 1) In der Website -Entwicklung betreibt JavaScript DOM zusammen mit HTML und CSS, um dynamische Effekte zu erzielen und Frameworks wie JQuery und React zu unterstützen. 2) Durch reaktnatives und ionisches JavaScript wird ein plattformübergreifendes mobile Anwendungen entwickelt. 3) Mit dem Elektronenframework können JavaScript Desktop -Anwendungen erstellen. 4) Node.js ermöglicht es JavaScript, auf der Serverseite auszuführen und unterstützt hohe gleichzeitige Anforderungen.

Python eignet sich besser für Datenwissenschaft und Automatisierung, während JavaScript besser für die Entwicklung von Front-End- und Vollstapel geeignet ist. 1. Python funktioniert in Datenwissenschaft und maschinellem Lernen gut und unter Verwendung von Bibliotheken wie Numpy und Pandas für die Datenverarbeitung und -modellierung. 2. Python ist prägnant und effizient in der Automatisierung und Skripten. 3. JavaScript ist in der Front-End-Entwicklung unverzichtbar und wird verwendet, um dynamische Webseiten und einseitige Anwendungen zu erstellen. 4. JavaScript spielt eine Rolle bei der Back-End-Entwicklung durch Node.js und unterstützt die Entwicklung der Vollstapel.

C und C spielen eine wichtige Rolle in der JavaScript -Engine, die hauptsächlich zur Implementierung von Dolmetschern und JIT -Compilern verwendet wird. 1) C wird verwendet, um JavaScript -Quellcode zu analysieren und einen abstrakten Syntaxbaum zu generieren. 2) C ist für die Generierung und Ausführung von Bytecode verantwortlich. 3) C implementiert den JIT-Compiler, optimiert und kompiliert Hot-Spot-Code zur Laufzeit und verbessert die Ausführungseffizienz von JavaScript erheblich.

Die Anwendung von JavaScript in der realen Welt umfasst Front-End- und Back-End-Entwicklung. 1) Zeigen Sie Front-End-Anwendungen an, indem Sie eine TODO-Listanwendung erstellen, die DOM-Operationen und Ereignisverarbeitung umfasst. 2) Erstellen Sie RESTFUFFUPI über Node.js und express, um Back-End-Anwendungen zu demonstrieren.

Zu den Hauptanwendungen von JavaScript in der Webentwicklung gehören die Interaktion der Clients, die Formüberprüfung und die asynchrone Kommunikation. 1) Dynamisches Inhaltsaktualisierung und Benutzerinteraktion durch DOM -Operationen; 2) Die Kundenüberprüfung erfolgt vor dem Einreichung von Daten, um die Benutzererfahrung zu verbessern. 3) Die Aktualisierung der Kommunikation mit dem Server wird durch AJAX -Technologie erreicht.

Es ist für Entwickler wichtig, zu verstehen, wie die JavaScript -Engine intern funktioniert, da sie effizientere Code schreibt und Leistungs Engpässe und Optimierungsstrategien verstehen kann. 1) Der Workflow der Engine umfasst drei Phasen: Parsen, Kompilieren und Ausführung; 2) Während des Ausführungsprozesses führt die Engine dynamische Optimierung durch, wie z. B. Inline -Cache und versteckte Klassen. 3) Zu Best Practices gehören die Vermeidung globaler Variablen, die Optimierung von Schleifen, die Verwendung von const und lass und die Vermeidung übermäßiger Verwendung von Schließungen.


Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

SecLists
SecLists ist der ultimative Begleiter für Sicherheitstester. Dabei handelt es sich um eine Sammlung verschiedener Arten von Listen, die häufig bei Sicherheitsbewertungen verwendet werden, an einem Ort. SecLists trägt dazu bei, Sicherheitstests effizienter und produktiver zu gestalten, indem es bequem alle Listen bereitstellt, die ein Sicherheitstester benötigen könnte. Zu den Listentypen gehören Benutzernamen, Passwörter, URLs, Fuzzing-Payloads, Muster für vertrauliche Daten, Web-Shells und mehr. Der Tester kann dieses Repository einfach auf einen neuen Testcomputer übertragen und hat dann Zugriff auf alle Arten von Listen, die er benötigt.

PHPStorm Mac-Version
Das neueste (2018.2.1) professionelle, integrierte PHP-Entwicklungstool

WebStorm-Mac-Version
Nützliche JavaScript-Entwicklungstools

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

DVWA
Damn Vulnerable Web App (DVWA) ist eine PHP/MySQL-Webanwendung, die sehr anfällig ist. Seine Hauptziele bestehen darin, Sicherheitsexperten dabei zu helfen, ihre Fähigkeiten und Tools in einem rechtlichen Umfeld zu testen, Webentwicklern dabei zu helfen, den Prozess der Sicherung von Webanwendungen besser zu verstehen, und Lehrern/Schülern dabei zu helfen, in einer Unterrichtsumgebung Webanwendungen zu lehren/lernen Sicherheit. Das Ziel von DVWA besteht darin, einige der häufigsten Web-Schwachstellen über eine einfache und unkomplizierte Benutzeroberfläche mit unterschiedlichen Schwierigkeitsgraden zu üben. Bitte beachten Sie, dass diese Software
