CI_Knight

且行善举,莫问前程。

0%

** 2016年07月03日更新**

  • 添加了daemon
  • 添加了colored logger
  • 优化了启动方式
  • 整理代码
  • 可选使用dnspod token进行授权验证

使用第三方的DDNS服务感觉总是不是太稳定,所以就利用DNSPOD的API编写了一个DDNS的Server。目前依然在开发当中,已经实现了动态域名的功能,接下来是添加更多的功能,使之更加稳定和易用。接下来就是要开始按照计划进行迭代。如果有兴趣一起开发的朋友可以邮箱联系我。

系统环境

ubuntu14.04 Desktop x64

编译nginx

apt-get安装的nginx并不支持websocket,需要添加nginx-push-stream-module模块,所以我们要重新编译nginx。

编译参考模块给出的 参考地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
git clone https://github.com/wandenberg/nginx-push-stream-module.git
# download nginx latest
wget http://nginx.org/download/nginx-1.9.10.tar.gz

# unpack, configure and build
tar zxvf nginx-1.9.10.tar.gz
cd nginx-1.9.10

# add Openssl model,generate Makefile
./configure --add-module=../nginx-push-stream-module --with-http_ssl_module

# if the HTTP rewrite module requires the PCRE library.
# sudo apt-get install libpcre3 libpcre3-dev
# sudo apt-get install openssl libssl-dev

make & sudo make install

更多config配置,使用./config –help默认安装在/usr/local/nginx下

配置websocket

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
# add the push_stream_shared_memory_size to your http context
http {
push_stream_shared_memory_size 32M;

# define publisher and subscriber endpoints in your server context
server {
location /channels-stats {
# activate channels statistics mode for this location
push_stream_channels_statistics;

# query string based channel id
push_stream_channels_path $arg_id;
}

location /pub {
# activate publisher (admin) mode for this location
push_stream_publisher admin;

# query string based channel id
push_stream_channels_path $arg_id;
}

location ~ /sub/(.*) {
# activate subscriber (streaming) mode for this location
push_stream_subscriber;

# positional channel path
push_stream_channels_path $1;
}
}
}

配置一个publisher,配置一个subscriber,以id区分每一个channel也可以直接nginx加载misc/nginx.conf

测试

推荐使用curl直接测试,也可以选择使用iocat测试,需要安装node.js以及npm

1
2
3
4
5
6
7
8
9
10
npm install iocat -g

# WebSocket Client
iocat ws://127.0.0.1:80/sub/1

# WebSocket Server
iocat -l -p 80

# or curl
curl -s -v -X POST 'http://127.0.0.1/pub?id=1' -d 'Hello World!'

因为有个国外的服务器搭了ss的服务,在电脑上使用比较方便.我自己本身有个可用的翻墙host,所以更青睐使用host直接上谷歌,并且github也可以加速.手机并不能使用ss,pad越狱之后才安装了ss的软件.也用过Privoxy将socks转成http,手机经常的切换代理也是很繁琐.

然后有现在解决办法,搭建了dns服务器.

dns服务器搭建在raspberry pi上,系统烧录的是debian系统.使用的dnsmasq软件,修改dns配置,配置翻墙host,修改dns服务器.

安装dnsmasq

1
sudo apt-get install dnsmasq

修改配置文件

1
sudo vi /etc/dnsmasq.conf

修改为

1
2
3
4
5
6
domain=raspberry.local
resolv-file=/etc/resolv.dnsmasq
min-port=4096
server=8.8.8.8
server=8.8.4.4
cache-size=10000

配置host

在/etc/dnsmasq.d/目录下创建gfw.conf,分析hosts文件结构

1
2
3
4
64.233.162.83    0.docs.google.com
64.233.162.83 0.drive.google.com
64.233.162.83 1.docs.google.com
64.233.162.83 1.drive.google.com

dnsmasq配置文件格式

1
2
3
4
address=/0.docs.google.com/64.233.162.83
address=/0.drive.google.com/64.233.162.83
address=/1.docs.google.com/64.233.162.83
address=/1.drive.google.com/64.233.162.83

批量处理hosts文件

1
awk -F ' ' '{print "address=/"$2"/"$1}' /etc/hosts

重启服务,修改dns到树莓派的ip

1
service dnsmasq restart

该篇文章对python内置函数,主要是元编程涉及到的类进行汇总.

__new__和__init__

因为使用markdown,__会被识别为加粗,标题可以使用\_\_来进行转义.或者使用```.

eg.

1
2
3
4
5
6
7
8
class A(object):
def __init__(self):
print "init"
def __new__(cls,*args, **kwargs):
print "new %s"%cls
return object.__new__(cls, *args, **kwargs)

A()

output:

1
2
new <class '__main__.A'>
init

解释

1
2
3
4
5
继承object的类才有__new__
__new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供
__new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例
__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
若__new__没有正确返回当前类cls的实例,那__init__是不会被调用的,即使是父类的实例也不行

__repr__

eg.

1
2
3
4
5
6
7
8
9
class A:
def __repr__(self):
return "repr"

def __str__(self):
return "str"

print str(A())
print repr(A())

output:

1
2
str
repr

解释

1
一般类的实现str将被转化为适于人阅读的模式,而repr更适于解释器读取.

__call__

eg.

1
2
3
4
5
6
7
8
9
class A:
def main(self, content):
return content

def __call__(self, content):
return self.main(content)

a = A()
print a('main')

output:

1
main

因为看lilac的源码,看到了带有颜色的logging模块,想到自己曾经在wordpress上写的一片文章《printf有趣的\033》,所以一并可以把文章迁移过来。

shell终端中

1
echo '\033[44;37;5m hello world\033[0m'

会打印出蓝底白字的hell world,这一效果在C中同样可以。

1
2
3
4
5
int main(int argc,char **argv)
{
printf("\033[44;37;5m hello world\033[0m");
return 0;
}

代码解析

1
2
3
4
5
\033     [1;     33;     1m;     xxxx     \033[0m

| | | | | |

开始 背景色 字体色 设置粗体 字符串 结束

其他参数

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
编码    颜色/动作  (m字符前使用)
0       重新设置属性到缺省设置
1       设置粗体
2       设置一半亮度(模拟彩色显示器的颜色)
4       设置下划线(模拟彩色显示器的颜色)
5       设置闪烁
7       设置反向图象
22      设置一般密度
24      关闭下划线
25      关闭闪烁
27      关闭反向图象
30      设置黑色前景
31      设置红色前景
32      设置绿色前景
33      设置棕色前景
34      设置蓝色前景
35      设置紫色前景
36      设置青色前景
37      设置白色前景
38      在缺省的前景颜色上设置下划线
39      在缺省的前景颜色上关闭下划线
40      设置黑色背景
41      设置红色背景
42      设置绿色背景
43      设置棕色背景
44      设置蓝色背景
45      设置紫色背景
46      设置青色背景
47      设置白色背景
49      设置缺省黑色背景

以及其他有趣代码

1
2
3
4
5
6
7
\033[2J          清除屏幕
\033[0q          关闭所有的键盘指示灯
\033[1q          设置“滚动锁定”指示灯 (Scroll Lock)
\033[2q          设置“数值锁定”指示灯 (Num Lock)
\033[3q          设置“大写锁定”指示灯 (Caps Lock)
\033[15:40H     把关闭移动到第15行,40列
\007              发蜂鸣生beep

所以Python中可以这样做一个染色类。

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
class Color(object):
colors = {
'black': 30,
'red': 31,
'green': 32,
'yellow': 33,
'blue': 34,
'magenta': 35,
'cyan': 36,
'white': 37,
'bgred': 41,
'bggrey': 100
}

prefix = '\033['

suffix = '\033[0m'

def __call__(self, text, color):
return self.colored(text, color)

def colored(self, text, color=None):
if color not in self.colors:
color = 'white'

clr = self.colors[color]
return (self.prefix+'%dm%s'+self.suffix) % (clr, text)

colored = Color()