树莓派忘记登录密码怎么办

借给同学之后自己把密码忘了……雅蠛蝶……可惜没把显示屏带回来,查了一圈之后灵机一动(* ̄▽ ̄)y

如果你有显示屏+USB键盘

  • 将SD卡插入电脑(windows下只挂载boot分区)
  • 打开boot分区,编辑command.txt(注意不要用记事本,可能会换行符坑爹)
  • 在第一行末尾加上init=/bin/sh,完成后大概是这样 ... root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait init=/bin/sh
  • 插卡,重启,连接键盘显示器
  • 出现shell后用passwd更改密码

没有的话呢?

  • 想办法让电脑和树莓派连通,可以用路由器,或者电脑装个dhcpd等
  • 生成一对密钥对,注意必须是openssh兼容格式而不是putty等密钥格式
  • 使用一个流行的linux发行版,将SD卡插入电脑;如果是老旧的版本,你可能需要手动挂载SD卡里的ext4分区
  • 进入/分区,在/root下建立一个.ssh文件夹(如果没有的话),并chmod 700
  • 在/root/.ssh/下建立一个文件authorized_keys,并chmod 600
  • 将公钥内容写入新创建的文件中
  • sync,umount
  • 插卡,重启,ssh使用root账户连接,并指定刚才的私钥
  • passwd修改密码

转载自 http://yooooo.us/2015/recover-raspi-password?variant=zh-hans

Linux下MySQL的root密码忘记解决方法

验证环境:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost ~]# rpm -qa | grep mysql
mysql-5.1.71-1.el6.i686
mysql-server-5.1.71-1.el6.i686
mysql-libs-5.1.71-1.el6.i686

[root@localhost ~]# lsb_release -a
LSB Version: :core-4.0-ia32:core-4.0-noarch:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-ia32:printing-4.0-noarch
Distributor ID: CentOS
Description: CentOS Linux release 6.0 (Final)
Release: 6.0
Codename: Final

[root@localhost ~]# uname -r
2.6.32-71.el6.i686

1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库。
因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的状态下,其他的用户也可以任意地登录和修改MySQL的信息。可以采用将MySQL对外的端口封闭,并且停止Apache以及所有的用户进程的方法实现服务器的准安全状态。最安全的状态是到服务器的Console上面操作,并且拔掉网线。

2.修改MySQL的登录设置:

1
vi /etc/my.cnf

在[mysqld]的段中加上一句:skip-grant-tables
例如:

1
2
3
4
[mysqld] 
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
skip-grant-tables

保存并且退出vi。

3.重新启动mysqld

1
2
3
# /etc/init.d/mysqld restart 
Stopping MySQL: [ OK ]
Starting MySQL: [ OK ]

4.登录并修改MySQL的root密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost ~]# mysql
Welcome to the MySQL monitor. Commands end with ; or \\g.
Your MySQL connection id is 3
Server version: 5.1.71 Source distribution
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.
mysql>UPDATE mysql.user SET Password = password ("new-password") WHERE User = 'root';
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> exit
Bye

5.将MySQL的登录设置修改回来

1
vi /etc/my.cnf

将刚才在[mysqld]的段中加上的skip-grant-tables删除,保存并且退出vi;

6.再次重新启动mysqld

1
2
3
# /etc/init.d/mysqld restart 
Stopping MySQL: [ OK ]
Starting MySQL: [ OK ]

7、使用新的密码登录,正常登录,搞定!

转载自 http://www.linuxidc.com/Linux/2013-07/87069.htm

重写了下博客的播放器

国庆无聊,对博客的播放器做了比较大幅度的修改,总结一下现有以下改进:

  1. 添加了”自动播放”复选框,可以由用户自主决定是否需要播放背景音乐(其实歌都不错的。。)
  1. 使用 node.js 重写了多标签的背景音乐控制器,主要是为了避免产生当用户打开多个标签后背景音乐同时播放的问题

抱着开源共享的想法,现在这里共享一下控制器源码。播放器的就不特地写了,都是前端的东西,右键”查看源代码”即可。如果有什么 bug,希望各位提出,谢谢各位。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
res.send('<h1>Welcome Realtime Server</h1>');
});

function count(o){
var t = typeof o;
if (t == 'string') {
return o.length;
} else if (t == 'object') {
var n = 0;
for (var i in o) {
n++;
}
return n;
}
return false;
};

Date.prototype.Format = function (fmt) {
var o = {
"M+": this.getMonth() + 1,
"d+": this.getDate(),
"h+": this.getHours(),
"m+": this.getMinutes(),
"s+": this.getSeconds(),
"q+": Math.floor((this.getMonth() + 3) / 3),
"S": this.getMilliseconds()
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}

var dump_log=function(msg) {
//console.log("\033[40;33m"+new Date().Format("yyyy-MM-dd hh:mm:ss")+"\033[0m\n"+msg+"\nNow "+count(clients)+" user(s) online.");
console.log(new Date().Format("yyyy-MM-dd hh:mm:ss")+"\n"+msg+"\nNow "+count(clients)+" user(s) online.");
}


var onlineCount = 0;
var index=0;
global['clients']={};

io.on('connection', function(socket){

socket.on('bindkey', function(str){
if (!str.match(/^[a-z0-9]{64}$/)) {
dump_log("data: "+str+"\nip: "+socket.handshake.address);
return false;
}
socket.bindkey = str;
socket.index = index;
if (typeof global['clients'][str]=="undefined") {
global['clients'][str]={};
onlineCount++;
}
global['clients'][str][index]={'playing':(count(global['clients'][str])==0?1:0),'socket':socket,'ip':socket.handshake.address,'index':index};
socket.emit("message",[0,index,global['clients'][str][index]['playing']]);
dump_log("bindkey: "+str+", index: "+index+", ip: "+socket.handshake.address);
index++;
});

socket.on('disconnect', function(){
delete global['clients'][socket.bindkey][socket.index];
if (count(global['clients'][socket.bindkey])!==0) {
for (var ckey in global['clients'][socket.bindkey]) {
var ready_play=global['clients'][socket.bindkey][ckey];
break;
}
ready_play['playing']=1;
ready_play.socket.emit("message",[1,ready_play.socket.index,1]);
} else {
delete global['clients'][socket.bindkey];
onlineCount--;
}
dump_log("bindkey: "+socket.bindkey+", index: "+socket.index+", ip: "+socket.handshake.address+" offline.");
});

});

http.listen(3000, function(){
console.log('listening on *:3000');
});

Docker 项目地址: https://github.com/jshensh/audioController

NodeJS中 package.json 解析

package.json 中包含各种所需模块以及项目的配置信息(名称、版本、许可证等)meta 信息。
包含可配置项

  • name 名称
  • 应用描述 description
  • 版本号 version
  • 应用的配置项 config
  • 作者 author
  • 资源仓库地址 respository
  • 授权方式 licenses
  • 目录 directories
  • 应用入口文件 main
  • 命令行文件 bin
  • 项目应用运行依赖模块 dependencies
  • 项目应用开发环境依赖 devDependencies
  • 运行引擎 engines
  • 脚本 script

简单模式

1
2
3
4
5
6
{

name: "myApp",

version :"0.0.1"
}

完整模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
{

"name": "myApp",
"version": "0.0.0",
"author" : "simple",
"description" : "Nodejs Package json介绍",
"keywords" : "javascript, nodejs",
"respository" : {
"type" :"git",
"url" :"http://path/to/url"
},

"bugs" : {
"url" : "http://path/to/bug",
"email" : "bug@example.com"
},
"contributors" : [

{"name" : "zhangsan", "email" : "zhangsan@example.com"

]

"license" : "MIT",
"engines" : { "node" : "0.10.x"},
"script" : {
"start" : "node index.js"
},
"private": true,
"scripts": {
"start": "node ./bin/www"
},

"dependencies": {
"express": "~4.9.0",
"body-parser": "~1.8.1",
"cookie-parser": "~1.3.3",
"morgan": "~1.3.0",
"serve-favicon": "~2.1.3",
"debug": "~2.0.0",
"jade": "~1.6.0"
},

"devDependencies": {
"bower" : "~1.2.8",
"grunt" : "~0.4.1",
"grunt-contrib-concat" : "~0.3.0",
"grunt-contrib-jshint" : "~0.7.2",
"grunt-contrib-uglify" : "~0.2.7",
"grunt-contrib-clean" : "~0.5.0",
"browserify" : "2.36.1",
"grunt-browserify" : "~1.3.0"
}
}

1.scripts
运行指定脚本命令。

2.
npm install express –save
npm install express –save-dev
上面代码表示单独安装express模块,
–save参数表示将该模块写入dependencies属性,
–save-dev表示将该模块写入devDependencies属性。

3.关于指定版本号
_(1)波浪号~(tilde)+指定版本:比如~1.2.2,表示安装1.2.x的最新版本(不低于1.2.2),但是不安装1.3.x,也就是说安装时不改变大版本号和次要版本号。 _

转载自 http://www.cnphp6.com/archives/57964?utm_source=tuicool

使用Node.js+Socket.IO搭建WebSocket实时应用

Web领域的实时推送技术,也被称作Realtime技术。这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新。它有着广泛的应用场景,比如在线聊天室、在线客服系统、评论系统、WebIM等。
20140611173333_407

WebSocket简介
谈到Web实时推送,就不得不说WebSocket。在WebSocket出现之前,很多网站为了实现实时推送技术,通常采用的方案是轮询 (Polling)和Comet技术,Comet又可细分为两种实现方式,一种是长轮询机制,一种称为流技术,这两种方式实际上是对轮询技术的改进,这些 方案带来很明显的缺点,需要由浏览器对服务器发出HTTP request,大量消耗服务器带宽和资源。面对这种状况,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽并实现真正意义上的实 时推送。
WebSocket协议本质上是一个基于TCP的协议,它由通信协议和编程API组成,WebSocket能够在浏览器和服务器之间建立双向连接, 以基于事件的方式,赋予浏览器实时通信能力。既然是双向通信,就意味着服务器端和客户端可以同时发送并响应请求,而不再像HTTP的请求和响应。
为了建立一个WebSocket连接,客户端浏览器首先要向服务器发起一个HTTP请求,这个请求和通常的HTTP请求不同,包含了一些附加头信 息,其中附加头信息”Upgrade: WebSocket”表明这是一个申请协议升级的HTTP请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。
一个典型WebSocket客户端请求头:
20140611173334_763
前面讲到WebSocket是HTML5中新增的一种通信协议,这意味着一部分老版本浏览器(主要是IE10以下版本)并不具备这个功能,通过百度统计的公开数据显示,IE8 目前仍以33%的市场份额占据榜首,好在chrome浏览器市场份额逐年上升,现在以超过26%的市场份额位居第二,同时微软前不久宣布停止对IE6的技 术支持并提示用户更新到新版本浏览器,这个曾经让无数前端工程师为之头疼的浏览器有望退出历史舞台,再加上几乎所有的智能手机浏览器都支持HTML5,所 以使得WebSocket的实战意义大增,但是无论如何,我们实际的项目中,仍然要考虑低版本浏览器的兼容方案:在支持WebSocket的浏览器中采用 新技术,而在不支持WebSocket的浏览器里启用Comet来接收发送消息。

WebSocket实战
本文将以多人在线聊天应用作为实例场景,我们先来确定这个聊天应用的基本需求。

需求分析
1、兼容不支持WebSocket的低版本浏览器。
2、允许客户端有相同的用户名。
3、进入聊天室后可以看到当前在线的用户和在线人数。
4、用户上线或退出,所有在线的客户端应该实时更新。
5、用户发送消息,所有客户端实时收取。
在实际的开发过程中,为了使用WebSocket接口构建Web应用,我们首先需要构建一个实现了 WebSocket规范的服务端,服务端的实现不受平台和开发语言的限制,只需要遵从WebSocket规范即可,目前已经出现了一些比较成熟的 WebSocket服务端实现,比如本文使用的Node.js+Socket.IO。为什么选用这个方案呢?先来简单介绍下他们两。

Node.js
Node.js采用C++语言编写而成,它不是Javascript应用,而是一个Javascript的运行环境,据Node.js创始人 Ryan Dahl回忆,他最初希望采用Ruby来写Node.js,但是后来发现Ruby虚拟机的性能不能满足他的要求,后来他尝试采用V8引擎,所以选择了 C++语言。
Node.js支持的系统包括*nux、Windows,这意味着程序员可以编写系统级或者服务器端的Javascript代码,交给 Node.js来解释执行。Node.js的Web开发框架Express,可以帮助程序员快速建立web站点,从2009年诞生至今,Node.js的 成长的速度有目共睹,其发展前景获得了技术社区的充分肯定。

Socket.IO
Socket.IO是一个开源的WebSocket库,它通过Node.js实现WebSocket服务端,同时也提供客户端JS库。Socket.IO支持以事件为基础的实时双向通讯,它可以工作在任何平台、浏览器或移动设备。
Socket.IO支持4种协议:WebSocket、htmlfile、xhr-polling、jsonp-polling,它会自动根据浏览 器选择适合的通讯方式,从而让开发者可以聚焦到功能的实现而不是平台的兼容性,同时Socket.IO具有不错的稳定性和性能。

编码实现
本文一开始的的插图就是效果演示图:可以点击这里查看在线演示,整个开发过程非常简单,下面简单记录了开发步骤:

安装Node.js
根据自己的操作系统,去Node.js官网下载安装即可。如果成功安装。在命令行输入node -v和npm -v应该能看到相应的版本号。

1
2
3
4
node -v 
v0.10.26
npm -v
1.4.6

搭建WebSocket服务端
这个环节我们尽可能的考虑真实生产环境,把WebSocket后端服务搭建成一个线上可以用域名访问的服务,如果你是在本地开发环境,可以换成本地ip地址,或者使用一个虚拟域名指向本地ip。
先进入到你的工作目录,比如 /workspace/wwwroot/plhwin/realtime.plhwin.com,新建一个名为 package.json的文件,内容如下:

1
2
3
4
5
6
{
"name": "realtime-server",
"version": "0.0.1",
"description": "my first realtime server",
"dependencies": {}
}

接下来使用npm命令安装express和socket.io

1
2
npm install --save express
npm install --save socket.io

安装成功后,应该可以看到工作目录下生成了一个名为node_modules的文件夹,里面分别是express和socket.io,接下来可以开始编写服务端的代码了,新建一个文件:index.js

1
2
3
4
5
6
7
8
9
10
11
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
res.send('<h1>Welcome Realtime Server</h1>');
});

http.listen(3000, function(){
console.log('listening on *:3000');
});

命令行运行node index.js,如果一切顺利,你应该会看到返回的listening on *:3000字样,这说明服务已经成功搭建了。此时浏览器中打开http://localhost:3000应该可以看到正常的欢迎页面。
如果你想要让服务运行在线上服务器,并且可以通过域名访问的话,可以使用Nginx做代理,在nginx.conf中添加如下配置,然后将域名(比如:realtime.plhwin.com)解析到服务器IP即可。

1
2
3
4
5
6
7
8
server
{
listen 80;
server_name realtime.plhwin.com;
location / {
proxy_pass http://127.0.0.1:3000;
}
}

完成以上步骤,http://realtime.plhwin.com:3000的后端服务就正常搭建了。
20140611173334_655

服务端代码实现
前面讲到的index.js运行在服务端,之前的代码只是一个简单的WebServer欢迎内容,让我们把WebSocket服务端完整的实现代码加入进去,整个服务端就可以处理客户端的请求了。完整的index.js代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="format-detection" content="telephone=no"/>
<meta name="format-detection" content="email=no"/>
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0" name="viewport">
<title>多人聊天室</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
<!--[if lt IE 8]><script src="./json3.min.js"></script><![endif]-->
<script src="http://realtime.plhwin.com:3000/socket.io/socket.io.js"></script>
</head>
<body>
<div id="loginbox">
<div style="width:260px;margin:200px auto;">
请先输入你在聊天室的昵称
<br/>
<br/>
<input type="text" style="width:180px;" placeholder="请输入用户名" id="username" name="username" />
<input type="button" style="width:50px;" value="提交" onclick="CHAT.usernameSubmit();"/>
</div>
</div>
<div id="chatbox" style="display:none;">
<div style="background:#3d3d3d;height: 28px; width: 100%;font-size:12px;">
<div style="line-height: 28px;color:#fff;">
<span style="text-align:left;margin-left:10px;">Websocket多人聊天室</span>
<span style="float:right; margin-right:10px;"><span id="showusername"></span> |
<a href="javascript:;" onclick="CHAT.logout()" style="color:#fff;">退出</a></span>
</div>
</div>
<div id="doc">
<div id="chat">
<div id="message" class="message">
<div id="onlinecount" style="background:#EFEFF4; font-size:12px; margin-top:10px; margin-left:10px; color:#666;">
</div>
</div>
<div class="input-box">
<div class="input">
<input type="text" maxlength="140" placeholder="请输入聊天内容,按Ctrl提交" id="content" name="content">
</div>
<div class="action">
<button type="button" id="mjr_send" onclick="CHAT.submit();">提交</button>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="./client.js"></script>
</body>
</html>

上面的html内容本身没有什么好说的,我们主要看看里面的4个文件请求:
1、realtime.plhwin.com:3000/socket.io/socket.io.js
2、style.css
3、json3.min.js
4、client.js

第1个JS是Socket.IO提供的客户端JS文件,在前面安装服务端的步骤中,当npm安装完socket.io并搭建起WebServer后,这个JS文件就可以正常访问了。
第2个style.css文件没什么好说的,就是样式文件而已。
第3个JS只在IE8以下版本的IE浏览器中加载,目的是让这些低版本的IE浏览器也能处理json,这是一个开源的JS,详见:http://bestiejs.github.io/json3/
第4个client.js是完整的客户端的业务逻辑实现代码,它的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
(function () {
var d = document,
w = window,
p = parseInt,
dd = d.documentElement,
db = d.body,
dc = d.compatMode == 'CSS1Compat',
dx = dc ? dd: db,
ec = encodeURIComponent;


w.CHAT = {
msgObj:d.getElementById("message"),
screenheight:w.innerHeight ? w.innerHeight : dx.clientHeight,
username:null,
userid:null,
socket:null,
//让浏览器滚动条保持在最低部
scrollToBottom:function(){
w.scrollTo(0, this.msgObj.clientHeight);
},
//退出,本例只是一个简单的刷新
logout:function(){
//this.socket.disconnect();
location.reload();
},
//提交聊天消息内容
submit:function(){
var content = d.getElementById("content").value;
if(content != ''){
var obj = {
userid: this.userid,
username: this.username,
content: content
};
this.socket.emit('message', obj);
d.getElementById("content").value = '';
}
return false;
},
genUid:function(){
return new Date().getTime()+""+Math.floor(Math.random()*899+100);
},
//更新系统消息,本例中在用户加入、退出的时候调用
updateSysMsg:function(o, action){
//当前在线用户列表
var onlineUsers = o.onlineUsers;
//当前在线人数
var onlineCount = o.onlineCount;
//新加入用户的信息
var user = o.user;

//更新在线人数
var userhtml = '';
var separator = '';
for(key in onlineUsers) {
if(onlineUsers.hasOwnProperty(key)){
userhtml += separator+onlineUsers[key];
separator = '、';
}
}
d.getElementById("onlinecount").innerHTML = '当前共有 '+onlineCount+' 人在线,在线列表:'+userhtml;

//添加系统消息
var html = '';
html += '<div class="msg-system">';
html += user.username;
html += (action == 'login') ? ' 加入了聊天室' : ' 退出了聊天室';
html += '</div>';
var section = d.createElement('section');
section.className = 'system J-mjrlinkWrap J-cutMsg';
section.innerHTML = html;
this.msgObj.appendChild(section);
this.scrollToBottom();
},
//第一个界面用户提交用户名
usernameSubmit:function(){
var username = d.getElementById("username").value;
if(username != ""){
d.getElementById("username").value = '';
d.getElementById("loginbox").style.display = 'none';
d.getElementById("chatbox").style.display = 'block';
this.init(username);
}
return false;
},
init:function(username){
/*
客户端根据时间和随机数生成uid,这样使得聊天室用户名称可以重复。
实际项目中,如果是需要用户登录,那么直接采用用户的uid来做标识就可以
*/
this.userid = this.genUid();
this.username = username;

d.getElementById("showusername").innerHTML = this.username;
this.msgObj.style.minHeight = (this.screenheight - db.clientHeight + this.msgObj.clientHeight) + "px";
this.scrollToBottom();

//连接websocket后端服务器
this.socket = io.connect('ws://realtime.plhwin.com:3000');

//告诉服务器端有用户登录
this.socket.emit('login', {userid:this.userid, username:this.username});

//监听新用户登录
this.socket.on('login', function(o){
CHAT.updateSysMsg(o, 'login');
});

//监听用户退出
this.socket.on('logout', function(o){
CHAT.updateSysMsg(o, 'logout');
});

//监听消息发送
this.socket.on('message', function(obj){
var isme = (obj.userid == CHAT.userid) ? true : false;
var contentDiv = '<div>'+obj.content+'</div>';
var usernameDiv = '<span>'+obj.username+'</span>';

var section = d.createElement('section');
if(isme){
section.className = 'user';
section.innerHTML = contentDiv + usernameDiv;
} else {
section.className = 'service';
section.innerHTML = usernameDiv + contentDiv;
}
CHAT.msgObj.appendChild(section);
CHAT.scrollToBottom();
});

}
};
//通过“回车”提交用户名
d.getElementById("username").onkeydown = function(e) {
e = e || event;
if (e.keyCode === 13) {
CHAT.usernameSubmit();
}
};
//通过“回车”提交信息
d.getElementById("content").onkeydown = function(e) {
e = e || event;
if (e.keyCode === 13) {
CHAT.submit();
}
};
})();

至此所有的编码开发工作全部完成了,在浏览器中打开http://demo.plhwin.com/chat/就可以看到效果了。
上面所有的客户端和服务端的代码可以从Github上获得,地址:https://github.com/plhwin/nodejs-socketio-chat

1
git clone https://github.com/plhwin/nodejs-socketio-chat.git

下载本地后有两个文件夹 client 和 server,client文件夹是客户端源码,可以放在Nginx/Apache的WebServer中,也可以放在Node.js的WebServer中。后面的server文件夹里的代码是websocket服务端代码,放在Node.js环境中,使用npm安装完 express 和 socket.io 后,node index.js 启动后端服务就可以了。

本例只是一个简单的Demo,留下2个有关项目扩展的思考:
1、假设是一个在线客服系统,里面有许多的公司使用你的服务,每个公司自己的用户可以通过一个专属URL地址进入该公司的聊天室,聊天是一对一的,每个公司可以新建多个客服人员,每个客服人员可以同时和客户端的多个用户聊天。
2、又假设是一个在线WebIM系统,实现类似微信,qq的功能,客户端可以看到好友在线状态,在线列表,添加好友,删除好友,新建群组等,消息的发送除了支持基本的文字外,还能支持表情、图片和文件。

转载自:http://www.plhwin.com/2014/05/28/nodejs-socketio/

初识 Docker - 使用 tenxcloud.com 搭建自己的应用

2015-09-30 更新:
daocloud 提供的配额更慷慨,各位有兴趣的话可以走我的邀请链接: https://account.daocloud.io/signup?invite_code=r7vcv0n2nenytal22llp,绑定微信的话送一个容器配额,一共三个。

需要搭 WordPress 的,请直接移步 http://www.freehao123.com/tenxcloud/

不知道什么是 Docker 的,请移步 http://baike.baidu.com/view/11854949.htm。我认为这和以前的 PaaS 类云平台(比如 appfog)差不多,都是布置完即成型,所有修改不保存的东西。
来看看探针: http://musics-johnshen.tenxcloud.net/ (5M 共享带宽,28 块一个月的,所以要是探针失效了别来找我,多半是我觉得不划算了)
好,接下来进入正题,如何在时速云上部署你的 PHP 应用。(其实官方有个 PHP 的 Hello world 的,但哔了狗的不能用)

首先,下载代码包并使用 git 上传到你喜欢的平台。然后打开时速云,选择构建,点击添加源代码,并登录你的 github 账号(当然你要是想只放个探针可以选快速构建,而不是添加源代码,然后在下一步中照我的填):
Screenshot_2015-09-29-14-31-26
选择你要构建的项目之后,你可以修改你的镜像名称,然后点击创建:
Screenshot_2015-09-29-14-31-52
创建完成之后:
Screenshot_2015-09-29-14-32-07
可点击你的项目的名称进入以下界面并快速部署你的应用:
Screenshot_2015-09-29-14-32-29
填上服务名称,创建即可:
Screenshot_2015-09-29-14-32-48

将树莓派系统迁移至 U 盘上

  新入手了个 pi 2B,先上张全家福(好吧图有点大)
20150924_195814
  那啥,把系统移动到 u 盘里的好处应该不用我说了吧,相信各位也应该百度过了。但是!百度下来的各种教程却是各种麻烦,有用 U-Boot 的,有用 BerryBoot 的,反正就是各种奇奇葩葩的第三方。其实,事情并没有那么复杂:

为确保不会发生错误,本文所有语句均在 root 用户下执行**

第一步:给 U 盘分区
  因为 U 盘比较大,所以不想全部用在树莓派上,当然各位要是土豪可以跳过这一步。
  在这里需要注意的是,常用文件分区(FAT32/NTFS/exFAT)一定要分在第一个区,树莓派的 ext3 要分在第二个区,不然傻乎乎的 Windows 会不认识。如图:
QQ图片20150924201713
  分区时可以不用管树莓派分区的文件系统,因为后续操作会覆盖掉。

第二步:将 sd 卡中的系统迁移至 U 盘
  很简单,用 dd 就行了。在这里我的 U 盘是 sda,第二个分区:

1
dd if=/dev/mmcblk0p2 of=/dev/sda2 bs=4M

  写完以后,修复 U 盘分区:

1
2
e2fsck -f /dev/sda2
resize2fs /dev/sda2

QQ截图20150924202346

第三步:重新配置启动设备 重要!!!
  挂载刚刚写完的分区上系统:

1
2
mkdir sda2
mount /dev/sda2 sda2

  修改以下两个文件,内容如图:

  • /boot/cmdline.txt
  • ./sda2/etc/fstab

2015-09-24-120659_480x320_scrot
  注意因为这是迁移完截的图,所以 fstab 的路径有点区别。

  然后 reboot 一下就大功告成啦。

【逆向爆菊】某DDOS事件逆向追踪。。。有人深挖过吗?

鄙人多次处理过各种被黑找幕后黑手事件。。。
如某领导早匿名邮件举报,干掉163拿到邮箱找发件人,,,某学生无聊干了当地教育局配合抓人,,,等等。。。
这还是第一次逆向DDOS事件。。。
某日一友人求助说维护的客户网站遭受SYN,毕竟政府用户有防火墙和IPS,告诉他设置防护就好了。。
第二日。。友人又来,说设置了没用。。。
给了我远程查看配置,发现某防火墙居然功能模块还有到期事件,正好所有模块到期,这防火墙就等于一台路由器了。。。
无奈只得导出日志分析IP手工添加ACL。。。

下面切入正题:
IP导出后,朋友自己加ACL,同时提到去年同一时间也有同样攻击。我怀疑攻击者目的,为什么防火墙功能模块刚到期就发起攻击?
怀着好奇心。。对导出的攻击IP进行扫描
-cache-4283972c60ea687cc15249676ff74e6c_1
其实如果是国内黑产,不过是1433、3389、3306等常见抓鸡。。ISP封了135 445 等端口SMB服务的利用可能性不大。
果真在记录IP中发现一台3306弱口令
-cache-af9551f2d9d65052ad7324c78207f2c7_2
然后大家就应该知道了。。。UDF.dll提权即可。。
由于时间已是凌晨2点,直接命令mysql连接,查了些信息
-cache-1161ee2a636574c820a506b4bf3e434b_3
-cache-c016d05db73a755a16f711d837c4db3d_4
可以看出一些IP。。
其中某IP
-cache-372565cecc1a67a9185b2a0d40fbc548_5
域名对应???
-cache-f257d616a19f1449cdae297826c9f248_6
邮箱对应???
-cache-5b461e8e2c2932a10a11f5e121963ea8_7
收款地址???
-cache-b5b3e354385559e34782748b535d98fc_8
淘宝走你???
-cache-3dc9cbb7c78e980ad40acaaae5d909fb_9
还用多少几句吗??
蒋华同学请小心了。。。
可惜没有下载病毒样本与其他进一步证据保留。。。否则大家都懂。。。

转载自 http://zone.wooyun.org/content/5808

CentOS 下 yum 安装 PostgreSQL

Configure YUM repository

1
vim /etc/yum.repos.d/CentOS-Base.repo

[base] and [updates] sections添加:

1
exclude=postgresql*

Install PGDG RPM file
go http://yum.postgresql.org and find your correct RPM.
For example, to install PostgreSQL 9.4 on CentOS 6 64-bit:
打开 http://yum.postgresql.org/repopackages.php#pg94 后找到 CentOS 6 - x86_64
then:

1
yum localinstall http://yum.postgresql.org/9.4/redhat/rhel-6-x86_64/pgdg-centos94-9.4-1.noarch.rpm

Install PostgreSQL
list available packages:

1
yum list postgres*

For example, to install a basic PostgreSQL 9.4 server:

1
yum install postgresql94-server

Other packages can be installed according to your needs.

配置
After installing the packages, a database needs to be initialized and configured.
PostgreSQL data directory(/var/lib/pgsql/9.4/data) contains all of the data files for the database.

Initialize
The first command (only needed once) is to initialize the database:

1
service postgresql-9.4 initdb

正在初始化数据库: [确定]

Startup
开机启动:

1
2
chkconfig postgresql-9.4 on
service postgresql-9.4 start

转载自 http://www.centoscn.com/CentosServer/sql/2014/0923/3821.html