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

xiaoxiao2021-02-27  298

*今天测试了一下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,所以『类似中国移动给全网信号内所有手机发消息的模式』亦可以理解『广播消息』

转载请注明原文地址: https://www.6miu.com/read-5967.html

最新回复(0)