nodeJS+express+Jade写一个局域网聊天应用(node基础)
为了复习一下nodeJS, 而且socketIO这东西听起来就好高端有木有, 而且有人写过了open, 也可以作为自己的参考有木有, 点击下载源代码;
express是4.x的版本, 跟以前的配置有些区别, 我才不管呢, 好用就好>﹏<;
按照正常的流程通过 node install 安装项目依赖, 项目的依赖如下;
"dependencies": {
"body-parser": "~1.8.4",
"cookie-parser": "~1.3.3",
"debug": "~2.0.0",
"express": "~4.9.8",
"jade": "~1.6.0",
"morgan": "~1.3.2",
"serve-favicon": "~2.1.7",
"socket.io": "~1.2.1"
}
(如果你像自己建项目的话 直接在命令行下 执行express projectName, express就会为你自动新建一个项目;)
先来看下高大上的服务端截图;
酷炫的客户端截图:
客户端的主要功能是发送消息, 如果用户不输入名字后台会分配一个名字给客户端;
服务端的主要功能是处理用户发送的数据, 然后把数据保存到json, 同时再把当前的新数据推送到所有 , 有连接到当前socket服务器的客户端;
简单的服务端流程如下:
//获取对应的依赖
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var http = require("http");
//主要就是通过socketIO的实现消息的实时推送;
var socketIo = require("socket.io");
//原生fileSystem模块,把数据保存起来的和获取数据用的;
var fs = require("fs"); .... var app = express();
var server = http.createServer(app);
//把socketIO绑定到服务上;
io = socketIo( server );
io.on('connection', function (socket) {
//socket的各种事件写在这边;
})
//启动服务, 监听的端口设置在3000;
server.listen( 3000 , function() {
console.log(" server is created ");
}); //使用jade模板, 以及设定视图目录;
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
服务端里面使用了封装了一个fs进行简单的文件操作,包括读取和写入的方法, 为了保存数据用的;
socket主要的几个事件要知道,包括:
//这个是socketIO初始化时候的事件;
io.on('connection', function (socket) {
//客户端发送 message给服务端的时候的事件, 用户发送过消息这个会触发;
socket.on('message', function(msg){});
socket.on('disconnect', function (msg) {});
//给当前连接的客户端回传一条消息;
socket.emit("message",{});
//给非当前的所有用户发送推送消息;
socket.broadcast.emit("message",{});
//你可以给客户端发送各种事件,名字你找自己起;
socket.emit('open',"sb");
socket.emit('hehe',"sb");
socket.emit('cnblogs',"sb");
});
所有的服务端代码(app.js)
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var http = require("http");
var socketIo = require("socket.io");
var fs = require("fs"); var routes = require('./routes/index');
//var users = require('./routes/users'); var app = express(); // view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade'); // uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
//app.use('port', process.env.PORT || 3000);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
//app.use('/users', users); // catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
}); // development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}; // production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
var server = http.createServer(app);
/*
var server = http.createServer(function(req, res){
res.end("hehe");
});
*/
io = socketIo( server ); var clients = {};
var appUtil = require("util")._extend({},{
getRandomId : function() {
var i=0;
i++;
return function() {
return "name"+(i++);
}
}(),
read : function( callback ) {
/*
* data.json保存的数据结构为 { key:[] Array };
* */
fs.readFile("data/data.json",function(err,data){
data = data.toString();
callback( JSON.parse(data).key );
});
},
write : function( writeData ,callback ) {
//读取数据并重写数据;
this.read(function(data) {
//我这个node读取单个json会返回一个a字符串,我就笑了,什么情况
// 如果你直接把json放在数组里面就没有这个问题;
//data = data[0] === "a" ? data.slice(1) : data;
data.push( writeData );
var temp = {
key : data
};
fs.writeFileSync("data/data.json",JSON.stringify(temp));
callback()
});
}
}); /*
* @desc WebSocket API, 端口3000, msg为对象:
* @param { } 传递空对象会返回 {msg : 读取文件的结果 JSON, name : 随机的一个name};
* @param { name : "xx" , type : "get" , msg : string }; //msg 读取文件的结果, type获取的类型
* @param { name : "xx" , type : "add" , msg : string }; //type 是 add为 添加, msg是指要添加的消息;
*/ io.on('connection', function (socket) {
socket.emit('open',"laile");//通知客户端已连接 // 这个闭包内的工具方法;
var sendMessage = function(name) {
appUtil.read(function(data) { //给当前连接的用户发送sock消息
socket.emit("message",{
name : name,
msg : data
});
//给非当前的所有用户发送消息;
socket.broadcast.emit("message",{
name : name,
msg : data
});
});
}; socket.on('message', function(msg){
console.log("来消息了");
console.log(msg);
//如果是没有name的,我们会分配一条name给用户;
var name = msg.name || appUtil.getRandomId(); if(!msg.name) {
sendMessage( name );
clients[name] = true;
}else if(msg.type == "get") {
sendMessage(name);
}else if( msg.type == "add" ) {
//我勒个去,因为readFile和appendFile是异步的, 所以要添加回调, 当然, 你可以用同步的readFileSync;
appUtil.write({ time : new Date().toString(), "name" : msg.name, "msg" : msg.msg}, function(){
sendMessage(name);
});
}; //如果是新用户的话, 广播一条叫做新用户登陆的信息;
console.log(name)
if(!clients[name]) {
clients[name] = true;
console.log("广播新用户登录的消息");
//注意 : 这个是socket,不是msg;
socket.broadcast.emit("refreshUser",name);
};
}); socket.on('disconnect', function (msg) {});
}); server.listen( 3000 , function() {
console.log(" server is created ");
}); module.exports = app;
客户端的代码你要引用socket.io模块下的socket.io/socket.io.js, 你通过 new WebSocket("ws://127.0.0.1") 一直会提示错误, 错误消息如下:
WebSocket connection to 'ws://127.0.0.1/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
然后通过socket.io这个库给我们提供的方法进行连接(我也不知道为什么这个可以连接,使用new WebSocket反正是连接不了):
var ws = io.connect('http://localhost:3000');
客户端的代码如下:
var ws = null;
var name = ""; var Ws = function(url) {
/*
只能说呵呵了, 使用new WebSocket无法连接到服务器, 提示握手前断开连接;
if(!window.WebSocket)
return null;
var ws = new WebSocket( 'ws:' + window.location.href.substring(window.location.protocol.length) );
*/
var ws = io.connect('http://localhost:3000');
ws.on('open',function(data) {
log(data);
ws.send({});
}); ws.on("refreshUser", function(msg){
$("<div></div>").html( msg+"登陆了哇" ).appendTo( $("#users") );
}); // socketIo连接开始握手的消息在chrome开发工具的请求中可以看到,
// 握手以后的消息传送无法截取;
ws.on("message", function(data) {
$("#output").html(" ");
name = data.name;
$("#name").val(data.name);
var arr = data.msg;
while( s = arr.shift() ) {
log( s );
};
window.scrollTo(0, 100000);
}); var sendMessage = function(msg){
ws.send(msg);
}; return ws; function log(s,e) {
var output = document.getElementById("output");
var p = document.createElement("p");
p.style.wordWrap = "break-word";
p.style.padding="10px";
p.style.background="#eee";
p.innerHTML = s.name + " at " + (new Date(s.time)).toDateString() + " :<br>==>> <b>"+ s.msg +"</b>";
output.appendChild(p);
};
};
function init() {
ws = Ws();
if(ws === null) {
alert("不支持webSocket!");
}; $("#ipt").keydown(function(e) {
var e = e || window.event;
if (e.keyCode === 13) {
var msg = $(this).val();
if (!msg) return;
ws.send({
type : "add",
msg : msg,
name : $("#name").val()
});
$(this).val('');
};
});
}; window.onload = init;
jade这个模板和express的路由什么的就不说了, 自己写个两行就懂了, 教程那么多, imooc屌炸天是不是哇, 明天复习JAVASCRIPT搞基程序设计3, 你懂的;
捐给给钱,这个我的支付宝账号:mayun.taobao.com;
nodeJS+express+Jade写一个局域网聊天应用(node基础)的更多相关文章
- 用c#写的一个局域网聊天客户端 类似小飞鸽
用c#写的一个局域网聊天客户端 类似小飞鸽 摘自: http://www.cnblogs.com/yyl8781697/archive/2012/12/07/csharp-socket-udp.htm ...
- webstorm创建nodejs + express + jade 的web 项目
webstorm创建nodejs + express + jade 的web 项目 前简单了解过nodejs,觉得用nodejs来做个网站也太麻烦了,要自己拼html的字符串返回,这能做网站嘛? 最近 ...
- vue+nodejs+express+mysql 建立一个在线网盘程序
vue+nodejs+express+mysql 建立一个在线网盘程序 目录 vue+nodejs+express+mysql 建立一个在线网盘程序 第一章 开发环境准备 1.1 开发所用工具简介 1 ...
- 打算写一个《重学Node.js》系列,希望大家多多支持
先放上链接吧,项目已经开始2周了:https://github.com/hellozhangran/happy-egg-server 想法 现在是2019年11月24日,还有人要开始学习Node.js ...
- nodejs+express+jade给我baby做个小相册
去年年底迎来了my little star.从此人生多了一个最重要的牵挂.生了宝宝全家人都太忙了.最近宝宝稍微大点了,终于有空可以研究下技术了.这是14年第一帖.废话不多了.开始吧 1.安装NTVS ...
- nodejs学习篇 (1)webstorm创建nodejs + express + jade 的web 项目
之前简单了解过nodejs,觉得用nodejs来做个网站也太麻烦了,要自己拼html的字符串返回,这能做网站嘛? 最近看到使用jade模板来开发,觉得挺新奇的,于是试了一把,也了解了一些特性,算是个新 ...
- 用Socket做一个局域网聊天工具(转)
原文:http://www.cnblogs.com/technology/archive/2010/08/15/1799858.html 程序设计成为简单的服务端和客户端之间的通信, 但通过一些方法可 ...
- node+express+jade搭建一个简单的"网站"
1.建立工程文件夹:my_jade 2.下载express和jade包到本地.我个人不喜欢下载成全局的,我喜欢下到工程文件夹中去. 3.建立相关的文件夹和文件. index.js: style.css ...
- 从 0 到 1 到完美,写一个 js 库、node 库、前端组件库
之前讲了很多关于项目工程化.前端架构.前端构建等方面的技术,这次说说怎么写一个完美的第三方库. 1. 选择合适的规范来写代码 js 模块化的发展大致有这样一个过程 iife => commonj ...
随机推荐
- Mecanim 动作复用示例
Mecanim动作复用 资源包 四个动画文件 一个Controller 不同的模型 让模型都生成Avter,然后让多个模型重用一套动作 复用动作预览 动画状态机 资源地址 Assets Store地址 ...
- java 27 - 2 反射之 反射的概述以及获取Class文件对象的方式
反射: JAVA语言的反射机制: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法: 对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调 ...
- HTML 学习笔记 CSS(选择器3)
CSS 属性选择器 属性选择器可以根据元素的额属性以及属性值来选择元素 例子1 如果 你希望把包含title的所有元素变成红色 *[title] {color:red} 例子2 与上面类似 可以只对有 ...
- HTML-学习笔记(属性)
HTML属性 HTML 标签可以拥有属性.属性提供了有关HTML元素更多的信息. 属性总是以键值对的形式出现.例如 name = "value"; 属性总是在HTML元素的开始标签 ...
- ie6-ie8中不支持opacity透明度的解决方法
ie6-ie8中是不支持的,需要加上下面这句话:filter: alpha(opacity=70);此外这种效果不能用ietester中的ie6测试,因为ietester的ie6这样写也是不透明的,但 ...
- Python的高级特性2:列表推导式,生成器与迭代器
一.列表推导式 1.列表推导式是颇具python风格的一种写法.这种写法除了高效,也更简短. In [23]: {i:el for i,el in enumerate(["one" ...
- linux 防火墙开启80端口永久保存
经常使用CentOS的朋友,可能会遇到和我一样的问题.开启了防火墙导致80端口无法访问,刚开始学习centos的朋友可以参考下.经常使用CentOS的朋友,可能会遇到和我一样的问题.最近在Linux ...
- sublime快捷键<转>
写在前面的话:平时做项目中在用eclipse和vs,但是对于一些小项目,感觉没有必要搞那么大的一个工具使用,比如写个小微商城,搞个小脚本了什么,所以就一直在用Sublime Text,界面清新简洁,没 ...
- win7的优化-1:隐藏我的电脑导航栏里的收藏等项目
1. Type regedit in RUN or Start Menu search box and press Enter. It'll open Registry Editor. 2. Now ...
- 利用ganymed-ssh2远程执行其它Linux机器上的shell命令
实际应用中,有时候需要从web管理界面上,远程去启动其它linux主机上的程序,利用ssh协议可以方便的满足这一需求.事实上hadoop架构中,从nn上启动dn时,就是利用了免密码ssh登录.gany ...