2012-01-09 35 views
5

Tôi đã triển khai c2dm và hoạt động tốt khi thiết bị nhận được tin nhắn và mọi thứ. Tuy nhiên, có một vấn đề mà tôi không thể tìm được giải pháp.Android, đẩy tin nhắn tới 1000 thiết bị nhanh

Khi xảy ra một sự kiện nào đó, tôi muốn đẩy nhanh cùng một tin nhắn tới vài nghìn thiết bị, tốt nhất là trong vòng một phút. Tôi biết rằng không có sự chắc chắn rằng thư sẽ được gửi và Google có thể trì hoãn thư do các trường hợp khác nhau.

Việc triển khai của tôi cho iOS là giống nhau ngoại trừ tất nhiên là phần gửi. Điều đó mất khoảng 5 giây cho 15.000 tin nhắn. Đối với 5000 tin nhắn cho Android phải mất hơn một giờ đó là cách để dài.

Có ai biết cách tăng tốc độ này không? Hoặc Google có ngăn chặn loại đẩy hàng loạt này để ngăn chặn spam không?

Phần C2DM của mã bên dưới. Đây là trong PHP nhưng tôi không có vấn đề đọc hầu hết các ngôn ngữ lập trình khác. Tôi sử dụng một tập lệnh để kết nối() một lần và sau đó lặp lại tất cả các thẻ và sử dụng sendMessage() để gửi mỗi tin nhắn. Sau khi tất cả các tin nhắn được gửi đi, nó ngắt kết nối().

<?php 
class C2DMclient 
{ 
    private $authKey = NULL; 
    private $ch = NULL; 

    function connect() { 
     $post_params = array(
      'Email'  => 'C2DM_USER', 
      'Passwd'  => 'C2DM_PWD', 
      'accountType' => 'HOSTED_OR_GOOGLE', 
      'source'  => 'appname', 
      'service'  => 'ac2dm', 
     ); 
     $first = true; 
     $data_msg = ''; 

     foreach($post_params as $key => $value) { 
      if($first) 
       $first = false; 
      else 
       $data_msg .= '&'; 

      $data_msg .= urlencode($key).'='.urlencode($value); 
     } 

     $x = curl_init('C2DM_CLIENTLOGIN'); 
     curl_setopt($x, CURLOPT_HEADER, true); 
     curl_setopt($x, CURLOPT_POST, true); 
     curl_setopt($x, CURLOPT_POSTFIELDS, $data_msg); 
     curl_setopt($x, CURLOPT_RETURNTRANSFER, true); 
     $response = curl_exec($x); 
     curl_close($x); 

     $pos = strpos($response, 'Auth='); 
     $this->authKey = trim(substr($response, 5 + $pos)); 
     $this->ch = curl_init(); 
     curl_setopt($this->ch, CURLOPT_URL, 'C2DM_SERVER'); 
    } 

    function disconnect() { 
     curl_close($this->ch); 
     $this->authKey = NULL; 
    } 

    function sendMessage($deviceToken, $message) { 
     $data = array(
      'registration_id' => $deviceToken, 
      'collapse_key' => 'ck_type', 
      'data.type'  => 'TYPE', 
      'data.message' => $message, 
      'data.title'  => 'Title' 
     ); 
     $headers = array('Authorization: GoogleLogin auth='.$this->authKey); 

     if($headers) 
      curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers); 

     curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0); 
     curl_setopt($this->ch, CURLOPT_POST, true); 
     curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); 
     curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data); 

     $messagedata = curl_exec($this->ch); 
      return TRUE; 
    } 
} 
?> 

EDIT: giải pháp mới dựa trên curl_multi_exec.

Tay cầm cuộn tròn được thu thập trong khi lặp qua kết quả truy vấn cơ sở dữ liệu. Sau khi một vài trăm xử lý curl được thu thập, sendMessages ($ chs) được gọi để gửi tất cả các tin nhắn đó. Tại thời điểm này tôi thu thập 700 tin nhắn trước khi gửi và dường như có tốc độ phân phối tốt và đủ nhanh, ~ 10 giây để gửi 5000 tin nhắn. Một con số cao hơn dường như ảnh hưởng đến tốc độ phân phối.

<?php 
class C2DMclient 
{ 
    private $authKey = NULL; 
    private $ch = NULL; 

    function connect() { 
     $post_params = array(
      'Email'  => 'C2DM_USER', 
      'Passwd'  => 'C2DM_PWD', 
      'accountType' => 'HOSTED_OR_GOOGLE', 
      'source'  => 'appname', 
      'service'  => 'ac2dm', 
     ); 
     $first = true; 
     $data_msg = ''; 

     foreach($post_params as $key => $value) { 
      if($first) 
       $first = false; 
      else 
       $data_msg .= '&'; 

      $data_msg .= urlencode($key).'='.urlencode($value); 
     } 

     $x = curl_init('C2DM_CLIENTLOGIN'); 
     curl_setopt($x, CURLOPT_HEADER, true); 
     curl_setopt($x, CURLOPT_POST, true); 
     curl_setopt($x, CURLOPT_POSTFIELDS, $data_msg); 
     curl_setopt($x, CURLOPT_RETURNTRANSFER, true); 
     $response = curl_exec($x); 
     curl_close($x); 

     $pos = strpos($response, 'Auth='); 
     $this->authKey = trim(substr($response, 5 + $pos)); 
    } 

    function getMessageCurlHandle($deviceToken, $message) { 
     $ch = curl_init(); 
     curl_setopt($ch, CURLOPT_URL, 'C2DM_SERVER'); 
     $data = array(
      'registration_id' => $deviceToken, 
      'collapse_key' => 'ck_type', 
      'data.type'  => 'TYPE', 
      'data.message' => $message, 
      'data.title'  => 'Title' 
     ); 
     $headers = array('Authorization: GoogleLogin auth='.$this->authKey); 

     if($headers) 
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 
     curl_setopt($ch, CURLOPT_POST, true); 
     curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 
     return $ch; 
    } 

    function sendMessages($chs) { 
     $mh = curl_multi_init(); 
     foreach($chs as $ch) { 
      curl_multi_add_handle($mh, $ch); 
     } 
     $active = null; 
     do { 
      $mrc = curl_multi_exec($mh, $active); 
     } while($mrc == CURLM_CALL_MULTI_PERFORM); 

     while($active && $mrc == CURLM_OK) { 
      if(curl_multi_select($mh) != -1) { 
       do { 
        $mrc = curl_multi_exec($mh, $active); 
       } while($mrc == CURLM_CALL_MULTI_PERFORM); 
      } 
     } 
     curl_multi_close($mh); 
    } 
} 
?> 

Trả lời

4

[Cập nhật] C2DM tại là deprecated. Đó là kế Google Cloud Messaging (GCM) hỗ trợ multiple receivers aka batch gửi:

{ "data": { 
    "score": "5x1", 
    "time": "15:10" 
    }, 
    "registration_ids": ["4", "8", "15", "16", "23", "42"] 
} 

[/ Cập nhật]

C2DM doesn't support batch gửi được nêu ra.

Tuy nhiên, bạn có thể gửi một số yêu cầu POST đến máy chủ C2DM cùng một lúc, tiếc là PHP không tự hỗ trợ đa luồng.

Hãy xem curl_multi_exec cho phép khả năng thực hiện một số yêu cầu cURL cùng một lúc.

+0

Tôi biết rằng C2DM không hỗ trợ gửi hàng loạt và cho phép tôi tạo một POST cho mỗi thư. Đối với một số lý do quá trình này mất một thời gian rất dài. Tôi sẽ xem curl_multi_exec. Có lẽ nó curl chính nó mất nhiều thời gian. Tôi sẽ dành nhiều thời gian hơn và trở lại nếu tôi thấy điều gì đó thú vị. – Daniel

+0

curl_multi_exec dường như là giải pháp. Sau khi thử nghiệm nó trong một vài ngày thời gian để gửi 5000 tin nhắn đã đi từ hơn một giờ đến một vài giây. Tuy nhiên, nó khá ngẫu nhiên nếu tin nhắn đã từng nhận được tin nhắn. Một số dường như bị lạc đường. Tôi đoán 2000 tin nhắn cùng một lúc là nhiều và tôi sẽ cố gắng tinh chỉnh điều này cho hiệu suất tối ưu so với tốc độ. Tôi sẽ cập nhật bài đăng gốc khi tôi nhận được thời gian. – Daniel

0

Ngoài ra tôi sẽ điều tra Firebase, tôi đã chơi với họ khá gần đây, và có vẻ như rất nhanh. Họ có API cho một loạt các khung công tác khá rộng. Mục tiêu của họ là đẩy các thay đổi vào bộ dữ liệu (thông điệp là một ví dụ hoàn hảo) rất nhanh chóng, vì vậy khi thay đổi xảy ra, họ sẽ gửi thông báo thông báo tới tất cả người dùng được kết nối.

https://www.firebase.com/

Các vấn đề liên quan