服务器端发送推送数据

服务器端发送推送数据
2011年12月26日
   由于网络各种原因,直到今天才吧服务端推送消息做好。。
  获取的消息如图,在用户不登陆客户端的情况下仍然可以接收到google服务器发送的消息。当然最重要的还是用户在第一次登陆客户端的时 候记录了用户的rid
  
  
  
  package com.lxl.C2DM;
  import java.util.Map;
  import java.util.TreeMap;
  import com.lxc.C2DM.http.URLPost;
  public class GetAuth {
  /**
  * @param args
  */
  public static void main(String[] args) {
  //这个rid是上一篇中获取的
  String rid = "APA91bFB6pnMraIPctzydZ7s6_FlWOP77SYhid999V2Q3w72wNs_bDFflXtNtomxdYjCaq5WGKfRITCs7QpbB8ToRmTykBy8Z-G1L70PxC77VpuNNxw8GzpnvU1yKwu_Xi9D_JsIMqSssP9Pk7UJAkkwQfzvBeV1Jw";
  String auth = getAUTH();
  if(auth == null){
  System.out.println("get auth fail!!");
  return;
  }
  Map message = new TreeMap();
  message.put("registration_id", rid); //识别手机的ID
  message.put("collapse_key", "1"); //消息的类型,同一类型消息只接收最后一条
  message.put("data.sender", "shineflag"); //消息以键值对形式出现,可有多个
  message.put("data.coins", "1000");
  postMessage(auth, message);
  }
  /**
  * 获取验证头,每次获取都是不同的,但我们只要任一个就行了
  * @return 验证头(失败为空) 获取权限
  */
  public static String getAUTH(){
  String url = "https://www.google.com/accounts/ClientLogin";//获取Auth的URL
  Map params = new TreeMap();
  params.put("accountType","HOSTED_OR_GOOGLE");
  params.put("Email","kb47161714@gmail.com");
  params.put("Passwd","xl4716171");
  params.put("service","ac2dm");
  params.put("source","bupt-c2dmdemo-1.0");
  String result = URLPost.PostURL(url, params,20*1000);
  String [] results = result.split("=");
  if(results == null || results.length message){
  String url = "https://android.apis.google.com/c2dm/send";//发送推送消息的URL(固定的)
  Map header = new TreeMap();
  header.put("Authorization","GoogleLogin auth="+auth); //推送消息的证证头
  String result = URLPost.PostURL(url, message, header, 20*1000);
  return result;
  }
  }
  package com.lxl.C2DM.http;
  import java.io.IOException;
  import java.net.HttpURLConnection;
  import java.net.MalformedURLException;
  import java.net.ProtocolException;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Map;
  import org.apache.http.HttpResponse;
  import org.apache.http.NameValuePair;
  import org.apache.http.client.HttpClient;
  import org.apache.http.client.entity.UrlEncodedFormEntity;
  import org.apache.http.client.methods.HttpPost;
  import org.apache.http.client.params.HttpClientParams;
  import org.apache.http.conn.ConnectTimeoutException;
  import org.apache.http.impl.client.DefaultHttpClient;
  import org.apache.http.message.BasicNameValuePair;
  import org.apache.http.params.BasicHttpParams;
  import org.apache.http.params.HttpConnectionParams;
  import org.apache.http.params.HttpParams;
  import org.apache.http.protocol.HTTP;
  import org.apache.http.util.EntityUtils;
  /**
  * 发送http请求的 工具类
  * @author Shineflag
  *
  */
  public class URLPost {
  /**
  * 发送http请求
  * @param url 请求的地址
  * @param params 请求的参数
  * @param header htttp头
  * @param timeout 超时时间
  * @return
  */
  public static String PostURL(String url,
  Map params, Map header,int timeout) {
  String result = null;
  HttpClient client = null;
  HttpResponse response = null;
  HttpPost postRequest = null;
  HttpParams httpParams = new BasicHttpParams(); // 创建HttpParams以用来设置HTTP参数(这一部分不是必需的)
  HttpConnectionParams.setConnectionTimeout(httpParams, 20 * 1000); // 设置连接超时
  HttpConnectionParams.setSoTimeout(httpParams, 20 * 1000); // 设置Socket超时
  HttpConnectionParams.setSocketBufferSize(httpParams, 8 * 1024); // Socket数据缓存默认8K
  HttpConnectionParams.setTcpNoDelay(httpParams, false);
  HttpConnectionParams.setStaleCheckingEnabled(httpParams, false);
  HttpClientParams.setRedirecting(httpParams, false);
  client = new DefaultHttpClient(httpParams);
  try {
  // 根据PHP情况设置超时
  client.getParams().setParameter(
  HttpConnectionParams.CONNECTION_TIMEOUT, timeout);
  client.getParams().setParameter(HttpConnectionParams.SO_TIMEOUT,
  timeout);
  List postParams = getpostParams(params);
  UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
  postParams, HTTP.UTF_8);
  postRequest = new HttpPost(url);
  setHeader(postRequest, header);
  postRequest.setEntity(formEntity);
  response = client.execute(postRequest);
  int responseCode = response.getStatusLine().getStatusCode();
  if (responseCode == HttpURLConnection.HTTP_OK) {
  result = EntityUtils.toString(response.getEntity());
  System.out.println("result = "+result);
  }else{
  System.out.println("responseCode ="+responseCode);
  }
  } catch (MalformedURLException e) {
  // 抛出这一异常指示出现了错误的 URL。或者在规范字符串中找不到任何合法协议,或者无法分析字符串
  } catch (ProtocolException e) {
  // 协议故障
  } catch (ConnectTimeoutException e) {
  } catch (IOException e) {
  } finally {
  }
  return result;
  }
  /**
  * 发送http请求
  * @param url 请求的地址
  * @param params 请求的参数
  * @param timeout 超时时间
  * @return
  */
  public static String PostURL(String url,
  Map params, int timeout) {
  String result = null;
  HttpClient client = null;
  HttpResponse response = null;
  HttpPost postRequest = null;
  HttpParams httpParams = new BasicHttpParams(); // 创建HttpParams以用来设置HTTP参数(这一部分不是必需的)
  HttpConnectionParams.setConnectionTimeout(httpParams, 20 * 1000); // 设置连接超时
  HttpConnectionParams.setSoTimeout(httpParams, 20 * 1000); // 设置Socket超时
  HttpConnectionParams.setSocketBufferSize(httpParams, 8 * 1024); // Socket数据缓存默认8K
  HttpConnectionParams.setTcpNoDelay(httpParams, false);
  HttpConnectionParams.setStaleCheckingEnabled(httpParams, false);
  HttpClientParams.setRedirecting(httpParams, false);
  client = new DefaultHttpClient(httpParams);
  try {
  // 根据PHP情况设置超时
  client.getParams().setParameter(
  HttpConnectionParams.CONNECTION_TIMEOUT, timeout);
  client.getParams().setParameter(HttpConnectionParams.SO_TIMEOUT,
  timeout);
  List postParams = getpostParams(params);
  UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
  postParams, HTTP.UTF_8);
  postRequest = new HttpPost(url);
  postRequest.setEntity(formEntity);
  response = client.execute(postRequest);
  int responseCode = response.getStatusLine().getStatusCode();
  if (responseCode == HttpURLConnection.HTTP_OK) {
  result = EntityUtils.toString(response.getEntity());
  System.out.println("result = "+result);
  }else{
  System.out.println("responseCode ="+responseCode);
  }
  } catch (MalformedURLException e) {
  // 抛出这一异常指示出现了错误的 URL。或者在规范字符串中找不到任何合法协议,或者无法分析字符串
  } catch (ProtocolException e) {
  // 协议故障
  } catch (ConnectTimeoutException e) {
  } catch (IOException e) {
  } catch (Exception e) {
  } finally {
  }
  return result;
  }
  /**
  * 生成请求参数
  * @param params
  * @return
  */
  public static List getpostParams(Map params){
  List postParams = new ArrayList(2);
  BasicNameValuePair param = null;
  for(String key:params.keySet()){
  param = new BasicNameValuePair(key, params.get(key));
  postParams.add(param);
  }
  return postParams;
  }
  /**
  * 设置http头
  * @param httpPost
  * @param header
  */
  private static void setHeader(HttpPost httpPost,Map header){
  if(httpPost == null || header == null)
  return;
  for(String key:header.keySet()){
  httpPost.addHeader(key, header.get(key));
  }
  }
  }
对于 gRPC服务器主动推送数据,可以使用服务器端流式 RPC(Server Streaming RPC)来实现。在 gRPC 中,服务器端流式 RPC 允许服务器在单个请求中流式传输多个响应消息给客户端。 以下是一个简单的示例代码,展示了如何在 gRPC服务器端主动推送数据客户端: 服务定义(.proto 文件): ```protobufsyntax = "proto3"; service MyService { rpc PushData(DataRequest) returns (stream DataResponse) {} } message DataRequest { // 可选的请求字段} message DataResponse { string data =1; } ``` 服务器端实现(使用 gRPC 的 Go语言示例): ```gopackage mainimport ( "context" "log" "net" "google.golang.org/grpc" ) type myServer struct{} func (s *myServer) PushData(req *pb.DataRequest, stream pb.MyService_PushDataServer) error { // 在这里可以根据需要生成响应数据,并通过流式发送客户端 for i :=0; i <10; i++ { resp := &pb.DataResponse{ Data: "Data " + strconv.Itoa(i), } if err := stream.Send(resp); err != nil { return err } } return nil} func main() { lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterMyServiceServer(s, &myServer{}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } } ``` 客户端实现(使用 gRPC 的 Go语言示例): ```gopackage mainimport ( "context" "log" "google.golang.org/grpc" ) func main() { conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() client := pb.NewMyServiceClient(conn) req := &pb.DataRequest{} stream, err := client.PushData(context.Background(), req) if err != nil { log.Fatalf("error calling PushData: %v", err) } for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { log.Fatalf("error receiving response: %v", err) } log.Printf("Received data: %s", resp.Data) } } ``` 上述示例中,服务器端实现了 `PushData` 方法,该方法返回一个 `stream DataResponse`,在方法内部通过循环向客户端发送多个响应消息。客户端通过调用 `PushData` 方法获取到一个 `stream DataResponse`,然后通过循环调用 `Recv` 方法来接收服务器端发送的多个响应消息。 这样,服务器就可以主动推送数据客户端了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值