移动客户端与服务器通信方式一

*今天测试了一下Java 给iOS客户端推送消息,包括静默推送 ,还有别名推送,其实是和token绑定在一块的,别名推送是用于 有用户分群需求的应用,什么时候绑定token,什么时候解绑(用户退出登录,一个用户手机,平板多设备登录),
玩转推送后有很多问题都迎刃而解了,但是一波未平一波又起啊!又会有新的问题出现,先看看代码吧*
iOS

// 说明 这是在用户同意推送的前提上进行的,如果用户没有同意,那下面的都是扯淡了,
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [[LY_NetWorking shareNetwork] checkNetworking];
    //这里要注意啊,注册一定写在 requestAuthorizationWithOptions 前面
    [application registerForRemoteNotifications];

    NSLog(@"launchOptions = %@",launchOptions);
    // 这里值兼容iOS 10以后
    UNUserNotificationCenter * center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
        NSLog(@"granted = %d",granted);
    }];


    return YES;
}

// 这个方法就厉害了,在后台(前台也可以)可以接收到静默推送啊
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
{
    NSLog(@" userInfo-- %@",userInfo);
    // 这里可以写你想实现的逻辑,
    completionHandler(UIBackgroundFetchResultNoData);

}
// iOS10新增:这个方法也厉害了,是什么,对,是接收消息前对消息的 提示类型进行设置,区分本地和远程通知哈
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
    //UNNotificationPresentationOptionAlert 有提示,
    //UNNotificationPresentationOptionBadge 有角标
    completionHandler(UNNotificationPresentationOptionSound);
}
//iOS10新增:处理后台点击通知的代理方法
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
{
    completionHandler();
}
// token
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(nonnull NSData *)deviceToken
{
    //正确写法
    NSString *deviceString = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    deviceString = [deviceString stringByReplacingOccurrencesOfString:@" " withString:@""];

    NSLog(@"deviceToken=%@",deviceString);
}
//获取DeviceToken失败
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
    NSLog(@"[DeviceToken Error]:%@\n",error.description);
}

Java部分


package com.sir.Push;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javapns.devices.Device;
import javapns.devices.implementations.basic.BasicDevice;
import javapns.notification.AppleNotificationServerBasicImpl;
import javapns.notification.PushNotificationManager;
import javapns.notification.PushNotificationPayload;
import javapns.notification.PushedNotification;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @author Sir
 * @version TODO
 */
public class Server {
    private static Log log = LogFactory.getLog(Server.class.getName());

     /************************************************

    需要javaPNS_2.2.jar包 注意导包
    如果用JSON串的话,还有到 那几个包

     ***************************************************/
    /**



     * apple推送方法

     * @param tokens   iphone手机的 device-token

     * @param path p12文件 

     * @param password  p12所需要的密码

     * @param message 推送的内容

     * @param count 角标

     * @param sendCount 单发还是群发  true单发 false群发

     */

    public void sendpush(List<String> tokens,String path, String password, String message,Integer count,boolean sendCount) {

    try {
        //message是一个json格式的串{"aps":{"alert":"iphone测试推送!"}}

            //这是一个 设置提示类型 的类
            PushNotificationPayload payLoad =  PushNotificationPayload.fromJSON(message);

            payLoad.addAlert("iphone测试推送ly3!   www.guligei.com"); //测试推送内容!

            payLoad.addBadge(count); // iphone角标

            payLoad.addSound("default"); // 铃声,默认


            PushNotificationManager pushManager = new PushNotificationManager();

            //true 正式推送 false测试推送

            pushManager.initializeConnection(new AppleNotificationServerBasicImpl(path, password, false));

            List<PushedNotification> notifications = new ArrayList<PushedNotification>(); 

            // 发送push 消息

            if (sendCount) {            
            Device device = new BasicDevice();

            device.setToken(tokens.get(0));

            PushedNotification notification = pushManager.sendNotification(device, payLoad, true);

            notifications.add(notification);

            } else {            
            List<Device> device = new ArrayList<Device>();

            for (String token : tokens) {

            device.add(new BasicDevice(token));

            }

            notifications = pushManager.sendNotifications(payLoad, device);

            }

            List<PushedNotification> failedNotifications = PushedNotification.findFailedNotifications(notifications);

            List<PushedNotification> successfulNotifications = PushedNotification.findSuccessfulNotifications(notifications);

            int failed = failedNotifications.size();

            int successful = successfulNotifications.size();



            if (successful > 0 && failed == 0) {
                System.out.print("推送成功:"+failedNotifications.toString());

            } else if (successful == 0 && failed > 0) {
            System.out.print("推送失败:"+failedNotifications.toString());

            } else if (successful == 0 && failed == 0) {
                System.out.print("推送失败:"+failedNotifications.toString());
            System.out.println("No notifications could be sent, probably because of a critical error");

            } else {
                System.out.print("推送失败:"+failedNotifications.toString());


            }

    // pushManager.stopConnection();

    } catch (Exception e) {

    e.printStackTrace();

    }

}

    /**
     * TODO
     * @param args
     */
    public static void main(String[] args) {
        Server send=new Server();
        List<String> tokens=new ArrayList<String>();
        tokens.add("cdc11cfbc06e421db828c330b16374137e57c9b8cb5916e85f5e1bfabfda9586");
        String path="dev_push.p12";
        String password="1234";
        //普通推送 在里面添加定义的字段,
//      String message="{'aps':{'alert':'测试test'}}";
        // 静默推送一定有 'content-available': 1,
        String message="{'aps':{'content-available': 1}}";
        Integer count=1;
        boolean sendCount=false;
        send.sendpush(tokens, path, password, message, count, sendCount);

    }

}

最近在研移动客户端 与 Java 后台的通信方式
一般移动端访问是通过get,post与服务器通信,但是这种半双工通信有个明显的缺点,那就是服务器不能主动发消息给客户端,必须是客户端请求,服务器回答模式,这样有时候就会满足不了我们的需求
*我总结了一下 有这样几种我知道的方式
1,Websocket ,不太熟悉 应该与socket 差不多哦

2,socket 客户端与服务器维持一个长连接(如何维护如此多的长连接,如果应对大规模的消息下发以及后续针对下发消息的各种统计动作都是技术难点),

3,推送,也是可以让服务器给客户端发消息的(现在应用一般都是全平台的,发送一条消息,应该同时发送给Android,iOS, WinPhone,Android端走自建的TCP长连接通道,iOS与WinPhone走自家的系统推送通道。那么意味着你服务端要维护这三套推送系统。显然对于小团队,要独自建立一套消息推送系统的难度非常大,所以市场上涌现出很多优秀的推送产品,帮开发者聚合这些推送方式,并提供统一的推送接口。国外如 Urban Airship, Parse等, 国内有JPush,百度云推送,信鸽)*

4,心跳包也能算一种,但是不好(时间太短对服务器压力大,太长链接不稳定,iOS后台还有很多限制),

在此之上,有衍生出针对消息的发布/订阅模型
客户端可以订阅某一个Topic,服务端根据Topic找到对应的Channel进行批量的消息下发。所有的客户端隐式的订阅的all这个opic,所以『类似中国移动给全网信号内所有手机发消息的模式』亦可以理解『广播消息』

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值