最近想弄一個Web IM,在web上做即時聊天有一定的困難,因為受限在http協定原生的特性:
client:request -> server:response -> 結束
傳輸一定要從client開始,而且一來一往誰也不能多,想做到server push有一定的難度,不像tcp raw socket自由度那麼高。
早期的聊天室會使用polling的方式定期 refresh (post back) 來更新頁面,同步的時間取決於refresh的頻率,但server loading也隨著頻率上升而增加。後來有了Ajax,頁面更新不用再一直閃爍,但還是有原本耗資源的問題。
近期較廣泛被使用的是Ajax搭配long polling,做到省資源又可以與server同步的效果。
Polling就是client定期的發request,long polling就是定期發request,但server不馬上response,而是等到有需要的時候再response (例如有人傳新訊息給你時),通常browser timeout都蠻長的,所以這段等待的期間相對polling就很省資源。如果還不是很懂,可以參考這一篇:Browser 與 Server 持續同步的作法介紹。
要做到long polling這個效果需要server support,server必需要把request object先keep住,等到有需要的時候再抓出來回應給client。用Tornado來舉例,就是RequestHandler被call時,先把Handler存起來,等到時機到了再執行finish() function。
下面列出幾種IM的 model,我想實現的是最後一種 ── 跨平台而且server可以隨著loading scale-up。
2012/03/04
2011/07/07
架設 Apple Push Notification Provider Server
參考下列兩篇教學
針對製作pem的地方我再加強解說(這邊我搞超久的)。
延續上一篇Apple Push Notification Service - 推播服務,此時你手上會有下列東西:
原文是請你到Keychain Assistant(鑰匙圈存取)去製作apns-dev-cert.p12的檔案,不過我就是沒辦法export出來。還好找到另一個手動解法:HowToCreatePKCS12Certificate
1. 打開"鑰匙圈存取",找到自己的Private Key(專用密鑰),按右建選擇匯出成private_key.p12
2. 將 aps_development.cer 轉換為 aps_development.pem
3. 將 private_key.p12 轉換為 private_key.pem
4. 去除轉發密碼
5. 合併 aps_development.pem 與 private_key_noenc.pem
有了 apns_dev.pem 這個憑證就可以傳送推播了!
傳送時的 message payload 格式也可以參考上面兩篇文章。
最後提供幾個人家implement好的APNS
Production server
ssl://gateway.push.apple.com:2195
Development server
ssl://gateway.sandbox.push.apple.com:2195
針對製作pem的地方我再加強解說(這邊我搞超久的)。
延續上一篇Apple Push Notification Service - 推播服務,此時你手上會有下列東西:
- CertificateSigningRequest.certSigningRequest (憑證申請書)
- aps_development.cer (憑證,從Apple下載的)
原文是請你到Keychain Assistant(鑰匙圈存取)去製作apns-dev-cert.p12的檔案,不過我就是沒辦法export出來。還好找到另一個手動解法:HowToCreatePKCS12Certificate
1. 打開"鑰匙圈存取",找到自己的Private Key(專用密鑰),按右建選擇匯出成private_key.p12
2. 將 aps_development.cer 轉換為 aps_development.pem
openssl x509 -in aps_development.cer -inform DER -out aps_development.pem -outform PEM}
3. 將 private_key.p12 轉換為 private_key.pem
openssl pkcs12 -nocerts -out private_key.pem -in private_key.p12
4. 去除轉發密碼
openssl rsa -out private_key_noenc.pem -in private_key.pem
5. 合併 aps_development.pem 與 private_key_noenc.pem
cat aps_development.pem private_key_noenc.pem > apns_dev.pem
有了 apns_dev.pem 這個憑證就可以傳送推播了!
傳送時的 message payload 格式也可以參考上面兩篇文章。
最後提供幾個人家implement好的APNS
- apns-php - 感覺是個強大的framework
- Simple APN Server - PHP sample
- apns-sharp - .Net CSharp sample
- apns-python-wrapper - Python
- 簡易架設iOS Push Notification:使用Urban Airship
Production server
2011/06/22
Apple Push Notification Service - 推播服務
最近在研究怎麼收送push notification,以及怎麼架設notification server。
推播服務的介紹及運作方式可以參考:
簡單來說就是每個iOS的app第一次開啓時會向apple註冊推播服務,然後得到專屬的device token,可以想像成擁有專屬的tunnel,再來只要向apple的server傳送message(JSON格式),並帶上target device token,server就會自動幫你轉傳給對方。
寫一個小小的測試程式
網站說明非常清楚,大致上的流程如下:
要求使用者開啓 Push notification 服務
Implement 3個 delegate
Sender (MacOS app):
參考資料
至於要如何架設APNS,可以參考下一篇:架設 Apple Push Notification Provider Server
推播服務的介紹及運作方式可以參考:
簡單來說就是每個iOS的app第一次開啓時會向apple註冊推播服務,然後得到專屬的device token,可以想像成擁有專屬的tunnel,再來只要向apple的server傳送message(JSON格式),並帶上target device token,server就會自動幫你轉傳給對方。
寫一個小小的測試程式
網站說明非常清楚,大致上的流程如下:
- 登入 iOS dev center 然後創建一個新的 App ID
- 開啓 push notification service
- 下載 "Development Push SSL Certificate" 及 "Provisioning Profile"
- 安裝 provisioning profile
- 設定 identifier
- Write the code to register from remote notification server and get "device token"
要求使用者開啓 Push notification 服務
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication]registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
}
Implement 3個 delegate
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
/* Get device token */
NSString *strDevToken = [NSString stringWithFormat:@"%@", deviceToken];
/* Replace '<', '>' and ' ' */
NSCharacterSet *charDummy = [NSCharacterSet characterSetWithCharactersInString:@"<> "];
strDevToken = [[strDevToken componentsSeparatedByCharactersInSet: charDummy] componentsJoinedByString: @""];
NSLog(@"Device token=[%@]", strDevToken);
/* 可以把token傳到server,之後server就可以靠它送推播給使用者了 */
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err
{
NSLog(@"Error=[%@]", err);
// TODO: when user do not allow push notification service, pop the warning message.
}
// This function called when receive notification and app is in the foreground.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
/* 把收到的推播列舉出來 */
for (id key in userInfo) {
NSLog(@"Key=[%@], Value=[%@]", key, [userInfo objectForKey:key]);
}
/* 印出 Badge number */
NSLog(@"Badge: %@", [[userInfo objectForKey:@"aps"] objectForKey:@"badge"];
}
Sender (MacOS app):
- Base on sample code "PushMeBaby"
- Install "Development Push SSL Certificate"
- Set target device token then send
參考資料
- iPhone Software Development: APNS Client Development Certificate Available Now
- 怎样编写Apple Push Notification服务器
至於要如何架設APNS,可以參考下一篇:架設 Apple Push Notification Provider Server
訂閱:
文章 (Atom)

