在mac下解压即可安装dmg文件即可,亲测在Yosemite下完全兼容。
luci修改代码后如何生效
因为luci有缓存机制,所以修改完lua代码后不会立即生效
删除/tmp目录里面的luci相关缓存即可。
1 2 3 |
rm -rf /tmp/luci-modulecache/* rm -rf /tmp/luci-indexcache |
或者直接重启系统也可以,效率比较低。
开发过程中可以打开/www/cgi-bin/luci
删除以下内容禁用缓存
1 |
luci.dispatcher.indexcache = "/tmp/luci-indexcache" |
阿里云启用Web攻击拦截后导致socket.io异常
部署完运行了一年没有出什么状况,最近发现WebSocket连接异常,在尝试建立WebSocket连接时服务器断开。node.js 提示 warn – websocket connection invalid 。
无奈先设置socket.io为轮询优先,先顶上保证业务。
1 |
websocketServer.set("transports", ["xhr-polling", "jsonp-polling"]); |
部署环境:
nginx1.5.4+node.js+express+socke.io
nginx监听80端口,socket.io监听3000端口,nginx根据域名代理。
问题描述:
1.远程访问WebSocket无法连接80端口,但是不通过nginx直接访问3000端口正常连接,chrome版本 36.0.1985.143 m
2.服务器上本地访问80,3000都正常。chrome版本 35.0.XXX
问题诊断:
1.首先排除chrome浏览器版本问题,升级服务器上chrome版本到36,依旧正常。
2.最近更新过一次服务器业务逻辑代码,但从未更新socket.io版本。根据现象初步估计为nginx代理有问题。
1 2 3 |
proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; |
反复修改conf文件 reload,问题依旧。nginx -s reload
3.为了排除nginx影响,停用nginx -s quit ,node.js直接listen80端口。远程访问问题依旧。
4.找到参考资料中的文章,想到可能是阿里云的问题。才记起最近启动了新出的web攻击拦截功能。停用几分钟后。问题解决。
Web攻击拦截
参考资料:
http://nolanlawson.com/2013/05/31/web-sockets-with-socket-io-node-js-and-nginx-port-80-considered-harmful/
OPENWRT添加新设备型号
以RT5350芯片为例
修改target/linux/ramips/image/makefile文件
修改base-files/lib/ramips.sh文件
target/linux/ramips/dts/ 目录下新增文件
target/linux/ramips/rt305x/profiles/ 目录下新增文件
….大概7.8个文件,具体修改方式参照里面已经有的设备几个,复制查找替换而已
可以参考 http://heffer.fedorapeople.org/openwrt/old/0002-ramips-add-Poray-M4.patch
如果使用了mkporayfw之类的firmware生成工具, tools/firmware-utils/ 也需要新增相关内容
1 2 3 |
cd trunk rm -rf tmp make menuconfig |
http://wiki.openwrt.org/doc/devel/add.new.device 官方说明,新版本变动较大。
—————————————————————————————————————————-
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 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
From 3ed1990677952a7c2f1aab046cfd9f13208c25d8 Mon Sep 17 00:00:00 2001 From: Felix Kaechele <felix@fetzig.org> Date: Fri, 5 Apr 2013 01:24:16 +0200 Subject: [PATCH 2/2] [ramips] add Poray M4 Signed-off-by: Felix Kaechele <felix@fetzig.org> Signed-off-by: Michel Stempin <michel.stempin@wanadoo.fr> Signed-off-by: Luis Soltero <lsoltero@globalmarinenet.com> --- target/linux/ramips/base-files/etc/diag.sh | 3 + .../ramips/base-files/etc/uci-defaults/02_network | 6 +- .../ramips/base-files/lib/preinit/06_set_iface_mac | 3 +- target/linux/ramips/base-files/lib/ramips.sh | 3 + .../ramips/base-files/lib/upgrade/platform.sh | 1 + target/linux/ramips/dts/M4-4M.dts | 103 +++++++++++++++++++++ target/linux/ramips/dts/M4-8M.dts | 103 +++++++++++++++++++++ target/linux/ramips/image/Makefile | 3 + target/linux/ramips/rt305x/profiles/poray.mk | 10 ++ 9 files changed, 232 insertions(+), 3 deletions(-) create mode 100644 target/linux/ramips/dts/M4-4M.dts create mode 100644 target/linux/ramips/dts/M4-8M.dts diff --git a/target/linux/ramips/base-files/etc/diag.sh b/target/linux/ramips/base-files/etc/diag.sh index c699695..f1ec82f 100755 --- a/target/linux/ramips/base-files/etc/diag.sh +++ b/target/linux/ramips/base-files/etc/diag.sh @@ -52,6 +52,9 @@ get_status_led() { m3) status_led="m3:blue:status" ;; + m4) + status_led="m4:blue:status" + ;; mofi3500-3gn) status_led="mofi3500-3gn:green:status" ;; diff --git a/target/linux/ramips/base-files/etc/uci-defaults/02_network b/target/linux/ramips/base-files/etc/uci-defaults/02_network index 4b6978b..db65b63 100755 --- a/target/linux/ramips/base-files/etc/uci-defaults/02_network +++ b/target/linux/ramips/base-files/etc/uci-defaults/02_network @@ -131,7 +131,8 @@ ramips_setup_interfaces() wli-tx4-ag300n) ucidef_set_interface_lan "eth0" ;; - m3) + m3 | + m4) swconfig dev rt305x set reset 1 ucidef_set_interface_lan "eth0" ;; @@ -214,7 +215,8 @@ ramips_setup_macs() wan_mac=$(macaddr_add "$lan_mac" 1) ;; - m3) + m3 | + m4) lan_mac=$(mtd_get_mac_binary factory 4) lan_mac=$(macaddr_add "$lan_mac" -1) ;; diff --git a/target/linux/ramips/base-files/lib/preinit/06_set_iface_mac b/target/linux/ramips/base-files/lib/preinit/06_set_iface_mac index 3c4951e..f46a123 100644 --- a/target/linux/ramips/base-files/lib/preinit/06_set_iface_mac +++ b/target/linux/ramips/base-files/lib/preinit/06_set_iface_mac @@ -68,7 +68,8 @@ preinit_set_mac_address() { mac=$(mtd_get_mac_binary factory 40) ifconfig eth0 hw ether $mac 2>/dev/null ;; - m3) + m3 | + m4) mac=$(mtd_get_mac_binary factory 4) mac=$(macaddr_add "$mac" -1) ifconfig eth0 hw ether $mac 2>/dev/null diff --git a/target/linux/ramips/base-files/lib/ramips.sh b/target/linux/ramips/base-files/lib/ramips.sh index ba409e9..b6609cd 100755 --- a/target/linux/ramips/base-files/lib/ramips.sh +++ b/target/linux/ramips/base-files/lib/ramips.sh @@ -141,6 +141,9 @@ ramips_board_detect() { *"Poray M3") name="m3" ;; + *"Poray M4") + name="m4" + ;; *"PWH2004") name="pwh2004" ;; diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh index 4833c5f..de6fcec 100755 --- a/target/linux/ramips/base-files/lib/upgrade/platform.sh +++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh @@ -39,6 +39,7 @@ platform_check_image() { freestation5 | hw550-3g | m3 | + m4 | mofi3500-3gn | mzk-w300nh2 | nbg-419n | diff --git a/target/linux/ramips/dts/M4-4M.dts b/target/linux/ramips/dts/M4-4M.dts new file mode 100644 index 0000000..a428bda --- /dev/null +++ b/target/linux/ramips/dts/M4-4M.dts @@ -0,0 +1,103 @@ +/dts-v1/; + +/include/ "rt5350.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "M4", "ralink,rt5350-soc"; + model = "Poray M4"; + + memorydetect { + ralink,memory = <0x0 0x200000 0x4000000>; + }; + + palmbus@10000000 { + sysc@0 { + ralink,pinmmux = "i2c", "spi", "uartlite", "jtag", "mdio", "sdram", "rgmii"; + ralink,uartmux = "gpio"; + ralink,wdtmux = <1>; + }; + + gpio0: gpio@600 { + status = "okay"; + }; + + spi@b00 { + status = "okay"; + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "pm25lq032"; + reg = <0 0>; + linux,modalias = "m25p80", "pm25lq032"; + spi-max-frequency = <10000000>; + + partition@0 { + reg = <0x0 0x30000>; + label = "u-boot"; + read-only; + }; + + partition@30000 { + reg = <0x30000 0x10000>; + label = "u-boot-env"; + read-only; + }; + + factory: partition@40000 { + reg = <0x40000 0x10000>; + label = "factory"; + read-only; + }; + + partition@50000 { + reg = <0x50000 0x3b0000>; + label = "firmware"; + }; + }; + }; + }; + + ethernet@10100000 { + status = "okay"; + }; + + esw@10110000 { + status = "okay"; + ralink,portmap = <0x2f>; + }; + + gpio-leds { + compatible = "gpio-leds"; + status { + label = "m4:blue:status"; + gpios = <&gpio0 9 1>; + }; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + reset { + label = "reset"; + gpios = <&gpio0 10 1>; + linux,code = <0x198>; + }; + }; + + wmac@10180000 { + status = "okay"; + ralink,mtd-eeprom = <&factory 0>; + }; + + ehci@101c0000 { + status = "okay"; + }; + + ohci@101c1000 { + status = "okay"; + }; +}; diff --git a/target/linux/ramips/dts/M4-8M.dts b/target/linux/ramips/dts/M4-8M.dts new file mode 100644 index 0000000..6e5b1f5 --- /dev/null +++ b/target/linux/ramips/dts/M4-8M.dts @@ -0,0 +1,103 @@ +/dts-v1/; + +/include/ "rt5350.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "M4", "ralink,rt5350-soc"; + model = "Poray M4"; + + memorydetect { + ralink,memory = <0x0 0x200000 0x4000000>; + }; + + palmbus@10000000 { + sysc@0 { + ralink,pinmmux = "i2c", "spi", "uartlite", "jtag", "mdio", "sdram", "rgmii"; + ralink,uartmux = "gpio"; + ralink,wdtmux = <1>; + }; + + gpio0: gpio@600 { + status = "okay"; + }; + + spi@b00 { + status = "okay"; + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "gd25q64"; + reg = <0 0>; + linux,modalias = "m25p80", "gd25q64"; + spi-max-frequency = <10000000>; + + partition@0 { + reg = <0x0 0x30000>; + label = "u-boot"; + read-only; + }; + + partition@30000 { + reg = <0x30000 0x10000>; + label = "u-boot-env"; + read-only; + }; + + factory: partition@40000 { + reg = <0x40000 0x10000>; + label = "factory"; + read-only; + }; + + partition@50000 { + reg = <0x50000 0x7b0000>; + label = "firmware"; + }; + }; + }; + }; + + ethernet@10100000 { + status = "okay"; + }; + + esw@10110000 { + status = "okay"; + ralink,portmap = <0x2f>; + }; + + gpio-leds { + compatible = "gpio-leds"; + status { + label = "m4:blue:status"; + gpios = <&gpio0 9 1>; + }; + }; + + gpio-keys-polled { + compatible = "gpio-keys-polled"; + #address-cells = <1>; + #size-cells = <0>; + poll-interval = <20>; + reset { + label = "reset"; + gpios = <&gpio0 10 1>; + linux,code = <0x198>; + }; + }; + + wmac@10180000 { + status = "okay"; + ralink,mtd-eeprom = <&factory 0>; + }; + + ehci@101c0000 { + status = "okay"; + }; + + ohci@101c1000 { + status = "okay"; + }; +}; diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile index c44a150..7bec7fb 100644 --- a/target/linux/ramips/image/Makefile +++ b/target/linux/ramips/image/Makefile @@ -319,6 +319,8 @@ Image/Build/Profile/FREESTATION5=$(call BuildFirmware/Default8M/$(1),$(1),freest Image/Build/Profile/M3=$(call BuildFirmware/Default4M/$(1),$(1),m3,M3) +Image/Build/Profile/M4=$(call BuildFirmware/DefaultDualSize/$(1),$(1),m4,M4) + Image/Build/Profile/MOFI3500-3GN=$(call BuildFirmware/Default8M/$(1),$(1),mofi3500-3gn,MOFI3500-3GN) Image/Build/Profile/NBG-419N=$(call BuildFirmware/Default4M/$(1),$(1),nbg-419n,NBG-419N) @@ -432,6 +434,7 @@ define Image/Build/Profile/Default $(call Image/Build/Profile/FREESTATION5,$(1)) $(call Image/Build/Profile/HW550-3G,$(1)) $(call Image/Build/Profile/M3,$(1)) + $(call Image/Build/Profile/M4,$(1)) $(call Image/Build/Profile/MOFI3500-3GN,$(1)) $(call Image/Build/Profile/MZKW300NH2,$(1)) $(call Image/Build/Profile/NBG-419N,$(1)) diff --git a/target/linux/ramips/rt305x/profiles/poray.mk b/target/linux/ramips/rt305x/profiles/poray.mk index 9c76c78..8774a2b 100644 --- a/target/linux/ramips/rt305x/profiles/poray.mk +++ b/target/linux/ramips/rt305x/profiles/poray.mk @@ -15,3 +15,13 @@ define Profile/M3/Description endef $(eval $(call Profile,M3)) + +define Profile/M4 + NAME:=Poray M4 + PACKAGES:=kmod-usb-core kmod-usb2 kmod-ledtrig-netdev kmod-ledtrig-timer +endef +define Profile/M4/Description + Package set for Poray M4 board +endef + +$(eval $(call Profile,M4)) -- 1.8.1.4 |
更多信息参考 http://80465.diandian.com/post/2013-09-04/40052660324
SecureCRT打开提示系统找不到指定文件
用SecureCRT串口调试的时候因为硬件问题导致WIN7蓝屏,重启后SecureCRT打开提示系统找不到指定文件。重新覆盖安装后依旧无法打开。估摸是配置文件的问题。
找到”C:UsersAdministratorAppDataRoamingVanDykeConfig”目录,然后删除即可。
随手送个免安装的SecureCRT(Version 5.5.0 (build 371))
下载链接: http://pan.baidu.com/s/1ntqKq61密码: w3vd
OpenWrt添加AllJoyn
1 |
src-git alljoyn https://git.allseenalliance.org/gerrit/core/openwrt_feed;attitude_adjustment |
2.更新安装源
1 2 |
./scripts/feeds update -a //更新软件包 ./scripts/feeds install -a // 安装软件包 |
3.添加编译
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
make menuconfig Network ---> < > alljoyn ---> < > alljoyn-about < > alljoyn-c < > alljoyn-config < > alljoyn-config-samples < > alljoyn-controlpanel < > alljoyn-controlpanel-samples < > alljoyn-notification < > alljoyn-notification-samples < > alljoyn-onboarding < > alljoyn-onboarding-samples < > alljoyn-sample_apps < > alljoyn-samples < > alljoyn-service_common |
1. Modify the openwrt/feeds.conf.default to add the following line:
src-git alljoyn https://git.allseenalliance.org/gerrit/core/openwrt_feed;attitude_adjustment
2. [Note] Remove the folder in openwrt/feeds/alljoyn/patches;
3. Build OpenWRT base on your router hardware model, remember to select alljoyn packages;
4. Flash the firmware to your router;
5. SSH to your router and execute the following commands to test alljoyn:
/usr/bin/alljoyn-daemon –fork
/usr/bin/AboutService
Open another terminal on the router and run
/usr/bin/AboutClient
Check the log message to make sure it works.
RT5350雷凌原厂固件默认DNS问题
现象:无线AP设置为【路由模式】,出现部分手机QQ游戏无法登陆【显示网络不给力】,但是浏览网页基本正常,速度偏慢。而【AP模式】一切正常。
第一感觉是DNS解析问题,于是手动指定了手机的DNS为8.8.8.8。发现果然游戏正常了。
然后重新设置为DHCP自动分配,查看了下自动获得的DNS为192.168.16.251和168.95.1.1。但是在无线AP界面上广域网DNS设置是202.101.172.35和202.101.172.47。
于是开始抓包。root@mako:/ # /data/local/tcpdump -p -s 0 -w /sdcard/dump/bad3.pcap
在手机上抓包分析后如下:
查了下获得的游戏服务器地址为202.55.10.189归属地为香港,而且是从168.95.1.1这台DNS服务器上获得,但是设置为手动指定DNS为8.8.8.8的时候获得游戏服务器地址是140.206.160.159归属地为上海联通。
很好奇手机上这个DNS是哪里获得的。于是查了下168.95.1.1,发现归属地为台湾电信。之前一直没注意到这是一个公网IP。猛然想到雷凌老窝在台湾。于是返回无线AP设置界面,看到下面这幺蛾子的事情:
原来在无线AP设置成【路由模式】的时候,局域网DNS服务器就起作用了。给手机分配的DNS并不是按常规想象的广域网设置页面上的那个DNS,而是这个局域网DNS。
总结:用雷凌原厂SDK的各位,如果设置为【路由模式】,就手动修改下局域网这个页面下么的DNS服务器地址,不要用这个168.95.1.1的坑货,否则你上网解析的优先都是境外服务器。
最后记录几个用到的命令:
1 2 3 4 5 6 7 8 9 |
adb shell //打开模拟终端 netstat -ano //查看网络连接 busybox netstat -p //显示连接的pid, ps:busybox下的netstat更为强大些 ./tcpdump -p -vv -s 0 -w /sdcard/dump/bad3.pcap //抓包并保存到文件 adb pull /sdcard/dump/bad3.pcap //拉文件到PC当前目录 |
用到的工具:tcpdump
MT7620换16M大小Flash
芯片:MT7620N
FALSH:25Q128 (winboard)
SDK中的Uboot只能识别4M,烧写大于4M的uImage提示如下:
1 2 3 4 |
Bytes transferred = 4450303 (43e7ff hex) NetBootFileXferSize= 0043e7ff raspi_erase_write: offs:50000, count:43e7ff Abort: image size larger than 3866624! |
查看/driver下的spi_flash.c,没有W25Q128BV,添加后重新编译Uboot然后烧入即可。
1 2 3 |
{ "W25Q32BV", 0xef, 0x40160000, 64 * 1024, 64, 0 }, //S25FL032K { "W25Q64BV", 0xef, 0x40170000, 64 * 1024, 128, 0 }, //S25FL064K { "W25Q128BV", 0xef, 0x40180000, 64 * 1024, 256, 0 }, //S25FL0128K |
Android ImageButton 点击切换背景图片
设置ImageButton按钮,点击后切换到另外一张图片,比如2张图片A,B,初始默认为A,点击完成后切换成B,再次点击,切换成A,这样的效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class MainActivity extends Activity { boolean is=true;//设备状态 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ImageButton btn = (ImageButton)findViewById(R.id.imageButton1); btn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (is) { ((ImageButton)v).setImageDrawable(getResources().getDrawable(R.drawable.on)); is=false; } else{ ((ImageButton)v).setImageDrawable(getResources().getDrawable(R.drawable.off)); is=true; } } }); } } |
代码下载:buttontest
XMPP协议研读
核心协议中文地址:http://wiki.jabbercn.org/RFC6120
以下部分摘自云风的blog: http://blog.codingnow.com/2008/11/xmpp.html
XMPP 抽象出一个在互联网上唯一的对象实体,用 JID 来表达。通常一个 JID 由三部分组成,node@domain/resource 。比 email 的表达形式多了一个 /resource 。这是因为 email 地址本身虽然可以表达一个实体,都是往往不够表达这个实体下的具体服务。就好比一个 ip 地址可以表示一台机器,但是我们还需要 port 号来表达这台机器具体提供的服务一样。
用过 gtalk 的人应该很喜欢 gtalk 可以在不同的地方同时登陆这个不错的特性。用过以后,才能体会,无论是 qq 还是 msn 还是 popo ,只允许一个登陆是多么愚蠢的设定。gtalk 其实遵守了标准的 XMPP 协议,它用来区别一个帐号(一般是一个 gmail 邮件地址)的多处登陆,正是利用了不同的 resource 标识。
XMPP 规范的最重要的一条通信协议就是,如何把消息从一个 JID 发送到另一个 JID (message)。这有点像 email 协议,但不同的是,它强调了实时性和安全性(虽然不是必须的)。因为 JID 可以在不同的 domain 下,这就需要 domain 间相互协作。对于 IM 网络来说(XMPP 远不只用于 IM 协议),就是不同的 IM 服务间互通。
对于 domain 下的 xmpp 服务的发现,利用了 DNS 协议的一些功能。xmpp 的 s2s 服务提供位置,放在了 DNS 的 SRV 记录里。你可以用 nslookup 做个试验,启动 nslookup ,输入 set type=SRV
然后查询 _xmpp-server._tcp.gmail.com
你会发现 gmail.com 的 xmpp s2s 服务地址已经端口号 5269 。同样,也可以查询 _xmpp-server._tcp.163.com
或 _xmpp-server._tcp.popo.163.com
查到网易 popo 的 xmpp 中转服务器地址。
btw, 查询 _xmpp-client._tcp.gmail.com
可以查到 gtalk 的 client 登陆地址,而网易 popo 则没有提供 xmpp client 登陆点。
按 RFC3920 所述,在 xmpp server 互联的时候,会优先尝试获取 domain 的 SRV 记录,如果失败就直接去连默认的 6259 端口。然后就可以开始握手协议。
xmpp 比较强调 s2s 的安全性,所以推荐的握手都是建立在 TLS 层之上,使用 SASL 认证。TLS 层需要服务器有一个数字证书,为了安全可信,建议是找个根证书签名。不过自己签名也行,只需要服务器缓存证书即可。握手过程在 RFC3920 中描述的非常细致,可以按照其编码,问题不大。需要注意的是,这里的 XML 流格式要求很精确,不允许传输多余的东西。我一度认为采用 XML 会导致协议的实现上非常臃肿,其实不然。采用 XML 只是一个表象,适合人阅读和调错而已。RFC 中特别要求不去实现 XML 中的某某特性就是一例。我们不应该为了 XML 而去 XML 。
其实 XMPP 的 c2s 和 s2s 并无太大区别,s2s 做的人手我想是因为开源项目和开源库比较少吧。而开源的 client 实现则是一大堆。c2s 和 s2s 的通讯都是基于那几条协议而已,s2s 的实现难点在于握手比较复杂(其实 c2s 也一样,只是很多库帮你做好了)。c2s 是共享一个 tcp 连接做双向通讯;而 s2s 则是用两条 TCP 连接。两条连接也一定程度上避免了 s2s 的欺骗,当然真正的安全来至于 TLS 和 SASL 的保障。DNS 毕竟是一个很脆弱的东西。
除了点对点消息外,XMPP 定义了消息的组播。也就是一个 JID 可以以自己的名义发布消息 (presence)。而服务器来决定该发给谁。发送目标是由订阅消息决定的。其它多个 JID 可以订阅某个 JID 的消息。对于 IM 来说,最常用的就是上线下线等状态变化消息了。
第三条即是对某个 JID 的状态进行设置和获取 (iq)。于 IM 应用来说,设置签名,昵称,状态等都依赖于它。
XMPP 的核心协议无非规定了以上三种通讯协议,此外规范了服务器间互连的握手认证方案。然后给出了一些错误信息的表述方法。稍微了解过之后,很容易编写。如果希望重造轮子的话,对于 C 语言开发者来说,最繁琐的可能是 XML 的解析于生成。我自己稍微考察了一下,有个叫 LoudMouth 的库还不错。
如果实现 s2s 网关的话,有些细节做起来可能很麻烦,比如查询 DNS 的 SRV 记录。这个在 jabberd 1.x 里其实有独立的模块实现好了,取来用即可 (见 dnsrv) 。而 TLS SASL 层的实现则早就有现成的开源库了。
实现一个 jabber server 或许比你想象的还简单。in.jabberd 居然只用 600 多行 C 代码就从零实现了一个 jabber 服务器。当然功能非常的简陋了。