基线 SVN r240

SVN-Revision: r240
This commit is contained in:
cyf
2025-02-06 06:46:06 +00:00
commit ab56a9bcf7
5317 changed files with 902274 additions and 0 deletions
@@ -0,0 +1,67 @@
using Lskj.Push.Push;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Common
{
public class APIRequestException:Exception
{
private ResponseWrapper responseRequest;
public APIRequestException(ResponseWrapper responseRequest)
: base(responseRequest.exceptionString)
{
this.responseRequest = responseRequest;
}
public HttpStatusCode Status
{
get
{
return this.responseRequest.responseCode;
}
}
public long MsgId
{
get
{
return responseRequest.jpushError.msg_id;
}
}
public int ErrorCode
{
get
{
return responseRequest.jpushError.error.code;
}
}
public String ErrorMessage
{
get
{
return responseRequest.jpushError.error.message;
}
}
private JpushError ErrorObject()
{
return responseRequest.jpushError;
}
public int RateLimitQuota()
{
return responseRequest.rateLimitQuota;
}
public int RateLimitRemaining()
{
return responseRequest.rateLimitRemaining;
}
public int RateLimitReset()
{
return responseRequest.rateLimitReset;
}
}
}
@@ -0,0 +1,107 @@
using Lskj.Push.Push.Mode;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Common
{
public class AudienceConverter : JsonConverter
{
/// <summary>
/// Platform whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
if (objectType == typeof(Audience))
return true;
return false;
}
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Audience audience = value as Audience;
if (audience == null)
{
return;
}
audience.Check();
if (audience.isAll())
{
writer.WriteValue(audience.allAudience);
//writer.WriteValue("alll");
}
else
{
var json = JsonConvert.SerializeObject(audience.dictionary);
writer.WriteRawValue(json);
}
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing property value of the JSON that is being converted.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Audience audience = Audience.all();
if (reader.TokenType == JsonToken.Null)
{
return null;
}
else if (reader.TokenType == JsonToken.String)
{
audience.allAudience = reader.Value.ToString();
}
else if (reader.TokenType == JsonToken.StartObject)
{
audience.allAudience = null;
Dictionary<string, HashSet<string>> dictionary=new Dictionary<string,HashSet<string>>();
string key="key";
HashSet<string> value=null;
while (reader.Read())
{
Debug.WriteLine("Type:{0},Path:{1}", reader.TokenType, reader.Path);
switch (reader.TokenType)
{
case JsonToken.StartObject:
break;
case JsonToken.PropertyName:
key = reader.Value.ToString();
break;
case JsonToken.StartArray:
value = new HashSet<string>();
break;
case JsonToken.String:
value.Add(reader.Value.ToString());
break;
case JsonToken.EndArray:
{
dictionary.Add(key,value);
}
break;
case JsonToken.EndObject:
return audience;
}
}
audience.dictionary = dictionary;
}
return audience;
}
}
}
@@ -0,0 +1,144 @@
using Lskj.Push.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Diagnostics;
using Newtonsoft.Json;
using Lskj.Push.Common.Resp;
namespace Lskj.Push.Common
{
class BaseHttpClient
{
private const String CHARSET = "UTF-8";
private const String RATE_LIMIT_QUOTA = "X-Rate-Limit-Limit";
private const String RATE_LIMIT_Remaining = "X-Rate-Limit-Remaining";
private const String RATE_LIMIT_Reset = "X-Rate-Limit-Reset";
protected const int RESPONSE_OK = 200;
//设置连接超时时间
private const int DEFAULT_CONNECTION_TIMEOUT = (20 * 1000); // milliseconds
//设置读取超时时间
private const int DEFAULT_SOCKET_TIMEOUT = (30 * 1000); // milliseconds
public ResponseWrapper sendPost(String url, String auth, String reqParams)
{
return this.sendRequest( "POST", url, auth, reqParams);
}
public ResponseWrapper sendDelete(String url, String auth, String reqParams)
{
return this.sendRequest("DELETE", url, auth, reqParams);
}
public ResponseWrapper sendGet(String url, String auth, String reqParams)
{
return this.sendRequest("GET", url, auth, reqParams);
}
/**
*
* method "POST" or "GET"
* url
* auth 可选
*/
public ResponseWrapper sendRequest(String method, String url, String auth,String reqParams)
{
Console.WriteLine("Send request - " + method.ToString() + " " + url + " "+ DateTime.Now);
if (null != reqParams)
{
Console.WriteLine("Request Content - " + reqParams +" "+ DateTime.Now);
}
ResponseWrapper result = new ResponseWrapper();
HttpWebRequest myReq = null;
HttpWebResponse response = null;
try
{
myReq = (HttpWebRequest)WebRequest.Create(url);
myReq.Method = method;
myReq.ContentType = "application/json";
if ( !String.IsNullOrEmpty(auth) )
{
myReq.Headers.Add("Authorization", "Basic " + auth);
}
if (method == "POST")
{
byte[] bs = UTF8Encoding.UTF8.GetBytes(reqParams);
myReq.ContentLength = bs.Length;
using (Stream reqStream = myReq.GetRequestStream())
{
reqStream.Write(bs, 0, bs.Length);
reqStream.Close();
}
}
response = (HttpWebResponse)myReq.GetResponse();
HttpStatusCode statusCode = response.StatusCode;
result.responseCode = statusCode;
if (Equals(response.StatusCode, HttpStatusCode.OK))
{
using (StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8))
{
result.responseContent = reader.ReadToEnd();
}
String limitQuota = response.GetResponseHeader(RATE_LIMIT_QUOTA);
String limitRemaining = response.GetResponseHeader(RATE_LIMIT_Remaining);
String limitReset = response.GetResponseHeader(RATE_LIMIT_Reset);
result.setRateLimit(limitQuota, limitRemaining, limitReset);
Console.WriteLine("Succeed to get response - 200 OK" +" "+ DateTime.Now);
Console.WriteLine("Response Content - {0}", result.responseContent +" "+ DateTime.Now);
}
}
catch (WebException e)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
HttpStatusCode errorCode = ((HttpWebResponse)e.Response).StatusCode;
string statusDescription = ((HttpWebResponse)e.Response).StatusDescription;
using (StreamReader sr = new StreamReader(((HttpWebResponse)e.Response).GetResponseStream(), System.Text.Encoding.UTF8))
{
result.responseContent = sr.ReadToEnd();
}
result.responseCode = errorCode;
result.exceptionString = e.Message;
String limitQuota = ((HttpWebResponse)e.Response).GetResponseHeader(RATE_LIMIT_QUOTA);
String limitRemaining = ((HttpWebResponse)e.Response).GetResponseHeader(RATE_LIMIT_Remaining);
String limitReset = ((HttpWebResponse)e.Response).GetResponseHeader(RATE_LIMIT_Reset);
result.setRateLimit(limitQuota, limitRemaining, limitReset);
Debug.Print(e.Message);
result.setErrorObject();
Console.WriteLine(string.Format("fail to get response - {0}", errorCode) + " "+ DateTime.Now);
Console.WriteLine(string.Format("Response Content - {0}", result.responseContent) + " "+ DateTime.Now);
throw new APIRequestException(result);
}
else
{//
throw new APIConnectionException(e.Message);
}
}
//这里不再抓取非http的异常,如果异常抛出交给开发者自行处理
//catch (System.Exception ex)
//{
// String errorMsg = ex.Message;
// Debug.Print(errorMsg);
//}
finally
{
if (response != null)
{
response.Close();
}
if(myReq != null)
{
myReq.Abort();
}
}
return result;
}
}
}
+51
View File
@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Common
{
public abstract class BaseResult
{
public const int ERROR_CODE_NONE = -1;
public const int ERROR_CODE_OK = 0;
public const String ERROR_MESSAGE_NONE = "None error message.";
public const int RESPONSE_OK = 200;
private ResponseWrapper responseResult;
public ResponseWrapper ResponseResult
{
get { return responseResult; }
set { responseResult = value; }
}
public abstract bool isResultOK();
// public override String getErrorMessage();
public int getRateLimitQuota() {
if (null != responseResult) {
return responseResult.rateLimitQuota;
}
return 0;
}
public int getRateLimitRemaining() {
if (null != responseResult) {
return responseResult.rateLimitRemaining;
}
return 0;
}
public int getRateLimitReset() {
if (null != responseResult) {
return responseResult.rateLimitReset;
}
return 0;
}
}
}
+19
View File
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Reflection;
namespace Lskj.Push.Common
{
public enum DeviceType
{
[Description("android")] android,
[Description("ios")] ios,
[Description("winphone")] winphone
}
}
@@ -0,0 +1,112 @@
using Lskj.Push.Push.Mode;
using Lskj.Push.Util;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Common
{
public class PlatformConverter:JsonConverter
{
/// <summary>
/// Platform whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
if (objectType == typeof(Platform))
return true;
return false;
}
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Platform platform = value as Platform;
if (platform == null)
{
return;
}
platform.Check();
if (platform.isAll())
{
writer.WriteValue(platform.allPlatform);
}
else
{
writer.WriteStartArray();
foreach (var item in platform.deviceTypes)
{
writer.WriteValue(item);
}
writer.WriteEndArray();
}
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing property value of the JSON that is being converted.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Platform platform = Platform.all();
if (reader.TokenType == JsonToken.Null)
{
return null;
}
else if(reader.TokenType==JsonToken.StartArray)
{
platform.allPlatform = null;
platform.deviceTypes = ReadArray(reader);
}
else if (reader.TokenType==JsonToken.String)
{
platform.allPlatform = reader.Value.ToString();
}
else
{
return null;
}
return platform;
}
private HashSet<string> ReadArray(JsonReader reader)
{
HashSet<string> list = new HashSet<string>();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.String:
list.Add(Convert.ToString(reader.Value, CultureInfo.InvariantCulture));
break;
case JsonToken.EndArray:
return list;
case JsonToken.Comment:
// skip
break;
default:
return null;
}
}
return null;
}
}
}
@@ -0,0 +1,81 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization.Json;
using System.Net;
using Lskj.Push.Util;
using System.Diagnostics;
using Lskj.Push.Push;
using Newtonsoft.Json;
namespace Lskj.Push.Common
{
public class ResponseWrapper
{
private const int RESPONSE_CODE_NONE = -1;
//private static Gson _gson = new Gson();
public JpushError jpushError;
public HttpStatusCode responseCode = HttpStatusCode.BadRequest;
private String _responseContent;
public String responseContent
{
get
{
return _responseContent;
}
set
{
_responseContent = value;
}
}
public void setErrorObject()
{
if(!string.IsNullOrEmpty(_responseContent))
{
jpushError = JsonConvert.DeserializeObject<JpushError>(_responseContent);
}
}
public int rateLimitQuota;
public int rateLimitRemaining;
public int rateLimitReset;
public bool isServerResponse()
{
return responseCode == HttpStatusCode.OK;
}
public String exceptionString;
public ResponseWrapper() {
}
public void setRateLimit(String quota, String remaining, String reset) {
if (null == quota) return;
try
{
if (quota != "" && StringUtil.IsInt(quota))
{
rateLimitQuota = int.Parse(quota);
}
if (remaining!="" && StringUtil.IsInt(remaining))
{
rateLimitRemaining = int.Parse(remaining);
}
if (reset!="" && StringUtil.IsInt(reset))
{
rateLimitReset = int.Parse(reset);
}
Console.WriteLine(string.Format("JPush API Rate Limiting params - quota:{0}, remaining:{1}, reset:{2} ", quota, remaining, reset) +" "+ DateTime.Now);
}
catch(Exception e)
{
Debug.Print(e.Message);
}
}
}
}
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Common
{
public class ServiceHelper
{
private const int MAX_BADGE_NUMBER = 99999;
private const int MIN = 100000;
private const int MAX = int.MaxValue;
public static int generateSendno()
{
Random random = new Random();
return random.Next((MAX - MIN) + 1) + MIN;
}
public static bool isValidIntBadge(int intBadge)
{
if (intBadge >= 0 && intBadge <= MAX_BADGE_NUMBER)
{
return true;
}
return false;
}
}
}
+18
View File
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Common
{
public enum TimeUnit
{
HOUR,
DAY,
MONTH
}
}
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Common.Resp
{
public class APIConnectionException:Exception
{
public APIConnectionException(String message):base(message)
{
}
}
}
@@ -0,0 +1,25 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Common.Resp
{
public class BooleanResult : DefaultResult
{
public bool result;
new public static BooleanResult fromResponse(ResponseWrapper responseWrapper)
{
BooleanResult tagListResult = new BooleanResult();
if (responseWrapper.isServerResponse())
{
tagListResult = JsonConvert.DeserializeObject<BooleanResult>(responseWrapper.responseContent);
}
tagListResult.ResponseResult = responseWrapper;
return tagListResult;
}
}
}
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Common.Resp
{
public class DefaultResult:BaseResult
{
public static DefaultResult fromResponse(ResponseWrapper responseWrapper)
{
DefaultResult result = null;
if (responseWrapper.isServerResponse())
{
result = new DefaultResult();
}
result.ResponseResult=responseWrapper;
return result;
}
public override bool isResultOK()
{
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
{
return true;
}
return false;
}
}
}
@@ -0,0 +1,38 @@
using Lskj.Push.Common;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Device
{
public class AliasDeviceListResult:BaseResult
{
public List<String> registration_ids ;
public AliasDeviceListResult()
{
registration_ids = null;
}
public override bool isResultOK()
{
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
{
return true;
}
return false;
}
public static AliasDeviceListResult fromResponse(ResponseWrapper responseWrapper)
{
AliasDeviceListResult aliasDeviceListResult = new AliasDeviceListResult();
if (responseWrapper.isServerResponse())
{
aliasDeviceListResult = JsonConvert.DeserializeObject<AliasDeviceListResult>(responseWrapper.responseContent);
}
aliasDeviceListResult.ResponseResult = responseWrapper;
return aliasDeviceListResult;
}
}
}
+177
View File
@@ -0,0 +1,177 @@
using Lskj.Push.Common;
using Lskj.Push.Common.Resp;
using Lskj.Push.Util;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Device
{
class DeviceClient : BaseHttpClient
{
public const String HOST_NAME_SSL = "https://device.jpush.cn";
public const String DEVICES_PATH = "/v3/devices";
public const String TAGS_PATH = "/v3/tags";
public const String ALIASES_PATH = "/v3/aliases";
private String appKey;
private String masterSecret;
public DeviceClient(String appKey, String masterSecret)
{
this.appKey = appKey;
this.masterSecret = masterSecret;
}
public TagAliasResult getDeviceTagAlias(String registrationId)
{
String url = HOST_NAME_SSL + DEVICES_PATH + "/" + registrationId;
String auth = Base64.getBase64Encode(this.appKey + ":" + this.masterSecret);
ResponseWrapper response = this.sendGet(url, auth, null);
return TagAliasResult.fromResponse(response);
}
public DefaultResult updateDeviceTagAlias(String registrationId, bool clearAlias, bool clearTag)
{
Preconditions.checkArgument(clearAlias || clearTag, "It is not meaningful to do nothing.");
String url = HOST_NAME_SSL + DEVICES_PATH + "/" + registrationId;
JObject top = new JObject();
if (clearAlias) {
top.Add("alias", "");
}
if (clearTag) {
top.Add("tags", "");
}
ResponseWrapper result = sendPost(url, Authorization(), top.ToString());
return DefaultResult.fromResponse(result);
}
public DefaultResult updateDeviceTagAlias(String registrationId,
String alias,
HashSet<String> tagsToAdd,
HashSet<String> tagsToRemove)
{
String url = HOST_NAME_SSL + DEVICES_PATH + "/" + registrationId;
JObject top = new JObject();
if (null != alias) {
top.Add("alias", alias);
}
JObject tagObject = new JObject();
if (tagsToAdd!=null)
{
JArray tagsAdd = JArray.FromObject(tagsToAdd);
if (tagsAdd.Count > 0)
{
tagObject.Add("add", tagsAdd);
}
}
if (tagsToRemove != null)
{
JArray tagsRemove = JArray.FromObject(tagsToRemove);
if (tagsRemove.Count > 0)
{
tagObject.Add("remove", tagsRemove);
}
}
if (tagObject.Count > 0) {
top.Add("tags", tagObject);
}
ResponseWrapper result = sendPost(url, Authorization(), top.ToString());
return DefaultResult.fromResponse(result);
}
public TagListResult getTagList()
{
String url = HOST_NAME_SSL + TAGS_PATH + "/";
String auth = Base64.getBase64Encode(this.appKey + ":" + this.masterSecret);
ResponseWrapper response = this.sendGet(url, auth, null);
return TagListResult.fromResponse(response);
}
public BooleanResult isDeviceInTag(String theTag, String registrationID)
{
String url = HOST_NAME_SSL + TAGS_PATH + "/" + theTag + "/registration_ids/" + registrationID;
ResponseWrapper response = this.sendGet(url, Authorization(), null);
return BooleanResult.fromResponse(response);
}
public DefaultResult addRemoveDevicesFromTag(String theTag,
HashSet<String> toAddUsers,
HashSet<String> toRemoveUsers)
{
String url = HOST_NAME_SSL + TAGS_PATH + "/" + theTag;
JObject top = new JObject();
JObject registrationIds = new JObject();
if (null != toAddUsers && toAddUsers.Count > 0)
{
JArray array = new JArray();
foreach (String user in toAddUsers) {
array.Add(JToken.FromObject(user));
}
registrationIds.Add("add", array);
}
if (null != toRemoveUsers && toRemoveUsers.Count > 0)
{
JArray array = new JArray();
foreach (String user in toRemoveUsers)
{
array.Add(JToken.FromObject(user));
}
registrationIds.Add("remove", array);
}
top.Add("registration_ids", registrationIds);
ResponseWrapper response = this.sendPost(url, Authorization(), top.ToString());
return DefaultResult.fromResponse(response);
}
public DefaultResult deleteTag(String theTag, String platform)
{
String url = HOST_NAME_SSL + TAGS_PATH + "/" + theTag;
if (null != platform) {
url += "?platform=" + platform;
}
ResponseWrapper response = this.sendDelete(url, Authorization(), null);
return DefaultResult.fromResponse(response);
}
// ------------- alias
public AliasDeviceListResult getAliasDeviceList(String alias, String platform)
{
String url = HOST_NAME_SSL + ALIASES_PATH + "/" + alias;
if (null != platform) {
url += "?platform=" + platform;
}
ResponseWrapper response = this.sendGet(url, Authorization(), null);
return AliasDeviceListResult.fromResponse(response);
}
public DefaultResult deleteAlias(String alias, String platform)
{
String url = HOST_NAME_SSL + ALIASES_PATH + "/" + alias;
if (null != platform) {
url += "?platform=" + platform;
}
ResponseWrapper response = this.sendDelete(url, Authorization(), null);
return DefaultResult.fromResponse(response);
}
private String Authorization()
{
Debug.Assert(!string.IsNullOrEmpty(this.appKey));
Debug.Assert(!string.IsNullOrEmpty(this.masterSecret));
String origin = this.appKey + ":" + this.masterSecret;
return Base64.getBase64Encode(origin);
}
}
}
@@ -0,0 +1,42 @@
using Lskj.Push.Common;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Device
{
public class TagAliasResult:BaseResult
{
public List<String> tags;
public String alias;
public TagAliasResult()
{
tags = null;
alias = null;
}
public override bool isResultOK()
{
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
{
return true;
}
return false;
}
public static TagAliasResult fromResponse(ResponseWrapper responseWrapper)
{
TagAliasResult tagAliasResult = new TagAliasResult();
if (responseWrapper.isServerResponse())
{
tagAliasResult = JsonConvert.DeserializeObject<TagAliasResult>(responseWrapper.responseContent);
}
tagAliasResult.ResponseResult = responseWrapper;
return tagAliasResult;
}
}
}
@@ -0,0 +1,38 @@
using Lskj.Push.Common;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Device
{
public class TagListResult:BaseResult
{
public List<String> tags ;
public TagListResult()
{
tags = null;
}
public override bool isResultOK()
{
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
{
return true;
}
return false;
}
public static TagListResult fromResponse(ResponseWrapper responseWrapper)
{
TagListResult tagListResult = new TagListResult();
if (responseWrapper.isServerResponse())
{
tagListResult = JsonConvert.DeserializeObject<TagListResult>(responseWrapper.responseContent);
}
tagListResult.ResponseResult = responseWrapper;
return tagListResult;
}
}
}
+595
View File
@@ -0,0 +1,595 @@
using Lskj.Push.Push.Mode;
using Lskj.Push.Push.Notification;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push
{
/// <summary>
/// JPush Api 常用方法,特殊的单独参考文档(http://docs.jpush.io/server/csharp_sdk/)
/// </summary>
public class JPushApi
{
#region Android相关API
/// <summary>
/// 发送所有人(Android终端)
/// </summary>
/// <param name="content">发送内容</param>
/// <returns></returns>
public static PushPayload PushObject_Android_All_Content(string content)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.all();
pushPayload.notification = new Notification().setAlert(content);
return pushPayload;
}
/// <summary>
/// 发送所有人(Android终端)
/// </summary>
/// <param name="content">发送内容</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_All_Content(string content, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.all();
pushPayload.notification = new Notification().setAlert(content);
foreach (var item in extras)
{
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送所有人(Android终端)
/// </summary>
/// <param name="title">发送标题</param>
/// <param name="content">发送内容</param>
/// <returns></returns>
public static PushPayload PushObject_Android_All_TitleWithContent(string title,string content)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.all();
pushPayload.notification = Notification.android(content, title);
return pushPayload;
}
/// <summary>
/// 发送所有人(Android终端)
/// </summary>
/// <param name="title">发送标题</param>
/// <param name="content">发送内容</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_All_TitleWithContent(string title, string content, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.all();
pushPayload.notification = Notification.android(content, title);
foreach (var item in extras)
{
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="content">发送内容(必填,不能为空)</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Message(string content, string alias, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.message = Message.content(content);
foreach (var item in extras)
{
pushPayload.message.AddExtras(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送指定终端(Android终端)
/// </summary>
/// <param name="content">发送内容</param>
/// <param name="alias">指定终端,现为操作员ID</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Alias_Content(string content, string alias)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.notification = new Notification().setAlert(content);
return pushPayload;
}
/// <summary>
/// 发送指定终端(Android终端)
/// </summary>
/// <param name="content">发送内容</param>
/// <param name="alias">指定多个终端,现为操作员ID</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Alias_Content(string content, string[] alias)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.notification = new Notification().setAlert(content);
return pushPayload;
}
/// <summary>
/// 发送指定终端(Android终端)
/// </summary>
/// <param name="content">发送内容</param>
/// <param name="alias">终端HashSet</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Alias_Content(string content, HashSet<string> alias)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.notification = new Notification().setAlert(content);
return pushPayload;
}
/// <summary>
/// 发送指定终端(Android终端)
/// </summary>
/// <param name="content">发送内容</param>
/// <param name="alias">指定多个终端,现为操作员ID</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Alias_Content(string content, string alias, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.notification = new Notification().setAlert(content);
foreach (var item in extras)
{
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送指定终端(Android终端)
/// </summary>
/// <param name="content">发送内容</param>
/// <param name="alias">指定多个终端,现为操作员ID</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Alias_Content(string content, string[] alias, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.notification = new Notification().setAlert(content);
foreach (var item in extras)
{
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送指定终端(Android终端)
/// </summary>
/// <param name="content">发送内容</param>
/// <param name="alias">终端HashSet</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Alias_Content(string content, HashSet<string> alias, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.notification = new Notification().setAlert(content);
foreach (var item in extras)
{
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送指定终端(Android终端)
/// </summary>
/// <param name="title">发送标题</param>
/// <param name="content">发送内容</param>
/// <param name="alias">指定终端,现为操作员ID</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Alias_TitleWithContent(string title, string content, string alias)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.notification = Notification.android(content, title);
return pushPayload;
}
/// <summary>
/// 发送指定终端(Android终端)
/// </summary>
/// <param name="title">发送标题</param>
/// <param name="content">发送内容</param>
/// <param name="alias">指定终端,现为操作员ID</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Alias_TitleWithContent(string title, string content, string[] alias)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.notification = Notification.android(content, title);
return pushPayload;
}
/// <summary>
/// 发送指定终端(Android终端)
/// </summary>
/// <param name="title">发送标题</param>
/// <param name="content">发送内容</param>
/// <param name="alias">指定终端,现为操作员ID</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Alias_TitleWithContent(string title, string content, HashSet<string> alias)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.notification = Notification.android(content, title);
return pushPayload;
}
/// <summary>
/// 发送指定终端(Android终端)
/// </summary>
/// <param name="title">发送标题</param>
/// <param name="content">发送内容</param>
/// <param name="alias">指定终端,现为操作员ID</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Alias_TitleWithContent(string title, string content, string alias, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.notification = Notification.android(content, title);
foreach (var item in extras)
{
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送指定终端(Android终端)
/// </summary>
/// <param name="title">发送标题</param>
/// <param name="content">发送内容</param>
/// <param name="alias">指定终端,现为操作员ID</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Alias_TitleWithContent(string title, string content, string[] alias, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.notification = Notification.android(content, title);
foreach (var item in extras)
{
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送指定终端(Android终端)
/// </summary>
/// <param name="title">发送标题</param>
/// <param name="content">发送内容</param>
/// <param name="alias">指定终端,现为操作员ID</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Alias_TitleWithContent(string title, string content, HashSet<string> alias, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.notification = Notification.android(content, title);
foreach (var item in extras)
{
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="content">发送内容(必填,不能为空)</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <param name="alias">指定终端,现为操作员ID</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Alias_Message(string content, Dictionary<string, object> extras, params string[] alias)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.message = Message.content(content);
foreach (var item in extras)
{
pushPayload.message.AddExtras(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送指定群组(Android终端)
/// </summary>
/// <param name="content">发送内容</param>
/// <param name="tags">群组标签</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Tags_Title(string content, string tags)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_tag(tags);
pushPayload.notification = new Notification().setAlert(content);
return pushPayload;
}
/// <summary>
/// 发送指定群组(Android终端)
/// </summary>
/// <param name="content">发送内容</param>
/// <param name="tags">群组标签</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Tags_Title(string content, string[] tags)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_tag(tags);
pushPayload.notification = new Notification().setAlert(content);
return pushPayload;
}
/// <summary>
/// 发送指定群组(Android终端)
/// </summary>
/// <param name="content">发送内容</param>
/// <param name="tags">群组标签</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Tags_Title(string content, HashSet<string> tags)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_tag(tags);
pushPayload.notification = new Notification().setAlert(content);
return pushPayload;
}
/// <summary>
/// 发送指定群组(Android终端)
/// </summary>
/// <param name="content">发送内容</param>
/// <param name="tags">群组标签</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Tags_Title(string content, string tags, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_tag(tags);
pushPayload.notification = new Notification().setAlert(content);
foreach (var item in extras)
{
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送指定群组(Android终端)
/// </summary>
/// <param name="content">发送内容</param>
/// <param name="tags">群组标签</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Tags_Title(string content, string[] tags, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_tag(tags);
pushPayload.notification = new Notification().setAlert(content);
foreach (var item in extras)
{
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送指定群组(Android终端)
/// </summary>
/// <param name="content">发送内容</param>
/// <param name="tags">群组标签</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Tags_Title(string content, HashSet<string> tags, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_tag(tags);
pushPayload.notification = new Notification().setAlert(content);
foreach (var item in extras)
{
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送指定群组(Android终端)
/// </summary>
/// <param name="title">发送标题</param>
/// <param name="content">发送内容</param>
/// <param name="tags">群组标签</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Tags_TileWithContent(string title, string content, string tags)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_tag(tags);
pushPayload.notification = Notification.android(content, title);
return pushPayload;
}
/// <summary>
/// 发送指定群组(Android终端)
/// </summary>
/// <param name="title">发送标题</param>
/// <param name="content">发送内容</param>
/// <param name="tags">群组标签数组</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Tags_TileWithContent(string title, string content, string[] tags)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_tag(tags);
pushPayload.notification = Notification.android(content, title);
return pushPayload;
}
/// <summary>
/// 发送指定群组(Android终端)
/// </summary>
/// <param name="title">发送标题</param>
/// <param name="content">发送内容</param>
/// <param name="tags">群组标签集合</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Tags_TileWithContent(string title, string content, HashSet<string> tags)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_tag(tags);
pushPayload.notification = Notification.android(content, title);
return pushPayload;
}
/// <summary>
/// 发送指定群组(Android终端)
/// </summary>
/// <param name="title">发送标题</param>
/// <param name="content">发送内容</param>
/// <param name="tags">群组标签</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Tags_TileWithContent(string title, string content, string tags, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_tag(tags);
pushPayload.notification = Notification.android(content, title);
foreach (var item in extras)
{
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送指定群组(Android终端)
/// </summary>
/// <param name="title">发送标题</param>
/// <param name="content">发送内容</param>
/// <param name="tags">群组标签数组</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Tags_TileWithContent(string title, string content, string[] tags, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_tag(tags);
pushPayload.notification = Notification.android(content, title);
foreach (var item in extras)
{
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送指定群组(Android终端)
/// </summary>
/// <param name="title">发送标题</param>
/// <param name="content">发送内容</param>
/// <param name="tags">群组标签集合</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Tags_TileWithContent(string title, string content, HashSet<string> tags, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_tag(tags);
pushPayload.notification = Notification.android(content, title);
foreach (var item in extras)
{
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="content">发送内容(必填,不能为空)</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <param name="alias">指定终端,现为操作员ID</param>
/// <returns></returns>
public static PushPayload PushObject_Android_Tags_Message(string content, Dictionary<string, object> extras, params string[] alias)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android();
pushPayload.audience = Audience.s_tag(alias);
pushPayload.message = Message.content(content);
foreach (var item in extras)
{
pushPayload.message.AddExtras(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 设置标签别名
/// </summary>
/// <returns></returns>
public static Audience PushObject_Android_SetAlias(string[] alias) {
return Audience.s_alias(alias);
}
/// <summary>
/// 设置标签
/// </summary>
/// <param name="tag"></param>
/// <returns></returns>
public static Audience PushObject_Android_SetTag(string[] tag) {
return Audience.s_tag(tag);
}
#endregion
#region Ios
public static PushPayload PushObject_Ios_Alias_TitleWithContent(string title, string content, string alias, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.android_ios();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.notification = Notification.ios(content);
foreach (var item in extras)
{
pushPayload.notification.IosNotification.AddExtra(item.Key, item.Value);
}
return pushPayload;
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="content">发送内容(必填,不能为空)</param>
/// <param name="extras">附加信息(object:只支持基本类型)</param>
/// <returns></returns>
public static PushPayload PushObject_Ios_Message(string content, string alias, Dictionary<string, object> extras)
{
PushPayload pushPayload = new PushPayload();
pushPayload.platform = Platform.ios();
pushPayload.audience = Audience.s_alias(alias);
pushPayload.message = Message.content(content);
foreach (var item in extras)
{
pushPayload.message.AddExtras(item.Key, item.Value);
}
return pushPayload;
}
#endregion
}
}
+227
View File
@@ -0,0 +1,227 @@
using Lskj.Push.Common;
using Lskj.Push.Common.Resp;
using Lskj.Push.Device;
using Lskj.Push.Push;
using Lskj.Push.Push.Mode;
using Lskj.Push.Report;
using Lskj.Push.Util;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push
{
/// <summary>
/// Main Entrance - 该类为JPush服务的主要入口
/// </summary>
public class JPushClient
{
private PushClient _pushClient;
private ReportClient _reportClient;
private DeviceClient _deviceClient;
/// <summary>
/// 带两个参数的构造函数,该状态下,ApnsProduction默认为false
/// </summary>
/// <param name="app_key">Portal上产生的app_key</param>
/// <param name="masterSecret">你的API MasterSecret</param>
public JPushClient(String app_key, String masterSecret)
{
_pushClient = new PushClient(app_key, masterSecret);
_reportClient = new ReportClient(app_key, masterSecret);
_deviceClient = new DeviceClient(app_key, masterSecret);
}
// ----------------------------- Push API
/// <summary>
/// 想某个设备或者某设别列表推送一条通知,或者消息
/// </summary>
/// <param name="PushPayload">推送的数据结构,包含平台信息推送目标,通知内容,消息内容与可选参数</param>
/// <returns>成功时返回sendno和messageid,失败时有异常抛出</returns>
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
/// <exception cref="APIConnectionException">包含错误的信息</exception>
/// <see cref="http://docs.jpush.cn/display/dev/Push-API-v3"/>
public MessageResult SendPush(PushPayload payload)
{
Preconditions.checkArgument(payload != null, "pushPayload should not be empty");
return _pushClient.sendPush(payload);
}
/// <summary>
/// 想某个设备或者某设别列表推送一条通知,或者消息
/// </summary>
/// <param name="PushPayload">推送的json结构,包含平台信息推送目标,通知内容,消息内容与可选参数</param>
/// <returns>成功时返回sendno和messageid,失败时有异常抛出</returns>
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
/// <exception cref="APIConnectionException">包含错误的信息</exception>
/// <see cref="http://docs.jpush.cn/display/dev/Push-API-v3"/>
public MessageResult SendPush(string payloadString)
{
Preconditions.checkArgument(!string.IsNullOrEmpty(payloadString), "payloadString should not be empty");
return _pushClient.sendPush(payloadString);
}
// ------------------------------- Report API
/// <summary>
/// Get received report.
/// </summary>
/// <param name="msgIds">100 msgids to batch getting is supported.</param>
/// <returns> Can be printed to JSON.</returns>
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
/// <exception cref="APIConnectionException">包含错误的信息</exception>
/// <see cref="100 msgids to batch getting is supported."/>
public ReceivedResult getReceivedApi(String msg_ids)
{
return _reportClient.getReceiveds(msg_ids);
}
/// <summary>
/// Get received report v3.
/// </summary>
/// <param name="msgIds">100 msgids to batch getting is supported.</param>
///
public ReceivedResult getReceivedApi_v3(String msg_ids)
{
return _reportClient.getReceiveds_v3(msg_ids);
}
/// <summary>
/// 用户统计查询接口,这个接口是vip用户专用
/// </summary>
/// <param name="timeUnit">时间单位,有三个取值:HOUR、DAY、MONTH</param>
/// <param name="start">起始时间</param>
/// <param name="duration">持续时间</param>
/// <returns>包含ios android的用户情况</returns>
public UsersResult getReportUsers(TimeUnit timeUnit, String start, int duration)
{
return _reportClient.getUsers(timeUnit, start, duration);
}
/// <summary>
/// 消息统计查询接口,这个接口是vip用户专用
/// </summary>
/// <param name="msgIds">用逗号分隔的多个消息id</param>
/// <returns>包含各个mssageid和ios android平台</returns>
public MessagesResult getReportMessages(params String[] msgIds)
{
return _reportClient.getReportMessages(msgIds);
}
// ------------------------------- Device API
/// <summary>
/// 获取当前设备的所有属性,包含tags,alias
/// </summary>
/// <param name="registrationId">设备的registrationID</param>
/// <returns>找不到的统计项是null,否则为统计项的值</returns>
public TagAliasResult getDeviceTagAlias(String registrationId)
{
return _deviceClient.getDeviceTagAlias(registrationId);
}
/// <summary>
/// 清理当前设备指定的属性,当前支持tags,alias
/// </summary>
/// <param name="clearAlias">是否清除alias</param>
/// <param name="clearTag">是否清除tags</param>
/// <returns>找不到的统计项是null,否则为统计项的值</returns>
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
/// <exception cref="APIConnectionException">包含错误的信息</exception>
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
public DefaultResult updateDeviceTagAlias(String registrationId, bool clearAlias, bool clearTag)
{
return _deviceClient.updateDeviceTagAlias(registrationId, clearAlias, clearTag);
}
/// <summary>
/// 更新当前设备指定的属性,当前支持tags,alias
/// </summary>
/// <param name="alias">alias名称,传递null:不改变,传递"":清空</param>
/// <param name="tagsToAdd">新添加的tags</param>
/// <param name="tagsToRemove">删除的tags</param>
/// <returns>更新成功时isResultOK==true</returns>
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
/// <exception cref="APIConnectionException">包含错误的信息</exception>
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
public DefaultResult updateDeviceTagAlias(String registrationId,
String alias,
HashSet<String> tagsToAdd,
HashSet<String> tagsToRemove)
{
return _deviceClient.updateDeviceTagAlias(registrationId, alias, tagsToAdd, tagsToRemove);
}
/// <summary>
/// 获取当前应用的所有标签
/// </summary>
/// <returns>标签列表</returns>
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
/// <exception cref="APIConnectionException">包含错误的信息</exception>
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
public TagListResult getTagList()
{
return _deviceClient.getTagList();
}
/// <summary>
/// 查询某个设备是否在tag下
/// </summary>
/// <param name="theTag">查询的tag </param>
/// <param name="registrationID">需要确认的设备的registrationID</param>
/// <returns>成功result=true,失败result=false</returns>
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
/// <exception cref="APIConnectionException">包含错误的信息</exception>
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
public BooleanResult isDeviceInTag(String theTag, String registrationID)
{
return _deviceClient.isDeviceInTag(theTag, registrationID);
}
/// <summary>
/// 为一个标签添加或者删除设备
/// </summary>
/// <param name="theTag">操作的tag </param>
/// <param name="toAddUsers">需要添加的registrationID的集合</param>
/// <param name="toRemoveUsers">需要删除的registrationID的集合</param>
/// <returns>成功isResultOK()=true,失败isResultOK()=false</returns>
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
/// <exception cref="APIConnectionException">包含错误的信息</exception>
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
public DefaultResult addRemoveDevicesFromTag(String theTag,
HashSet<String> toAddUsers,
HashSet<String> toRemoveUsers)
{
return _deviceClient.addRemoveDevicesFromTag(theTag, toAddUsers, toRemoveUsers);
}
/// <summary>
/// 删除一个标签,以及标签与设备之间的关联关系
/// </summary>
/// <param name="theTag">要删除的tag </param>
/// <param name="platform">可选参数,不填则默认为所有平台</param>
/// <returns>成功result=true,失败result=false</returns>
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
/// <exception cref="APIConnectionException">包含错误的信息</exception>
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
public DefaultResult deleteTag(String theTag, String platform)
{
return _deviceClient.deleteTag(theTag, platform);
}
/// <summary>
/// 查询别名
/// </summary>
/// <param name="alias">要查询的别名 </param>
/// <param name="platform">可选参数,不填则默认为所有平台</param>
/// <returns>返回alias的列表</returns>
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
/// <exception cref="APIConnectionException">包含错误的信息</exception>
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
public AliasDeviceListResult getAliasDeviceList(String alias, String platform)
{
return _deviceClient.getAliasDeviceList(alias, platform);
}
/// <summary>
/// 删除别名,以及该别名与设别之间的绑定关系
/// </summary>
/// <param name="alias">要删除的别名 </param>
/// <param name="platform">可选参数,不填则默认为所有平台</param>
/// <returns>成功isResultOK()=true,失败isResultOK()=false</returns>
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
/// <exception cref="APIConnectionException">包含错误的信息</exception>
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
public DefaultResult deleteAlias(String alias, String platform)
{
return _deviceClient.deleteAlias(alias, platform);
}
}
}
+128
View File
@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{D77C7B9E-3694-400D-BEE7-AFC99E63E55B}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Lskj.Push</RootNamespace>
<AssemblyName>Lskj.Push</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>..\..\Debug\AllMethodXml\Lskj.Push.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\引用DLL\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Common\APIRequestException.cs" />
<Compile Include="Common\AudienceConverter.cs" />
<Compile Include="Common\BaseHttpClient.cs" />
<Compile Include="Common\BaseResult.cs" />
<Compile Include="Common\DeviceType.cs" />
<Compile Include="Common\PlatformConverter.cs" />
<Compile Include="Common\ResponseWrapper.cs" />
<Compile Include="Common\resp\APIConnectionException.cs" />
<Compile Include="Common\resp\BooleanResult.cs" />
<Compile Include="Common\resp\DefaultResult.cs" />
<Compile Include="Common\ServiceHelper.cs" />
<Compile Include="Common\TimeUnit.cs" />
<Compile Include="Device\AliasDeviceListResult.cs" />
<Compile Include="Device\DeviceClient.cs" />
<Compile Include="Device\TagAliasResult.cs" />
<Compile Include="Device\TagListResult.cs" />
<Compile Include="JPushApi.cs" />
<Compile Include="JPushClient.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Push\Audience\AudienceTarget.cs" />
<Compile Include="Push\Audience\AudienceType.cs" />
<Compile Include="Push\MessageResult.cs" />
<Compile Include="Push\Mode\Audience.cs" />
<Compile Include="Push\Mode\Message.cs" />
<Compile Include="Push\Mode\Notification.cs" />
<Compile Include="Push\Mode\Options.cs" />
<Compile Include="Push\Mode\Platform.cs" />
<Compile Include="Push\Mode\PushPayload.cs" />
<Compile Include="Push\Mode\PushUser.cs" />
<Compile Include="Push\Notification\AndroidNotification.cs" />
<Compile Include="Push\Notification\IosNotification.cs" />
<Compile Include="Push\Notification\PlatformNotification.cs" />
<Compile Include="Push\Notification\WinphoneNotification.cs" />
<Compile Include="Push\PushClient.cs" />
<Compile Include="Report\MessagesResult.cs" />
<Compile Include="Report\ReceivedResult.cs" />
<Compile Include="Report\ReportClient.cs" />
<Compile Include="Report\UsersResult.cs" />
<Compile Include="Util\Base64.cs" />
<Compile Include="Util\JsonTool.cs" />
<Compile Include="Util\Md5.cs" />
<Compile Include="Util\Preconditions.cs" />
<Compile Include="Util\StringUtil.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Lskj.Push")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Lskj.Push")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("4dfb63b4-d0f8-44cd-82fb-4b4a5c124296")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 内部版本号
// 修订号
//
// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+63
View File
@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace Lskj.Push.Properties {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// 返回此类使用的缓存的 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Lskj.Push.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 使用此强类型资源类,为所有资源查找
/// 重写当前线程的 CurrentUICulture 属性。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Lskj.Push.Util;
namespace Lskj.Push.Push.Audience
{
public class AudienceTarget
{
public AudienceType audienceType{get;private set;}
public HashSet<string> valueBuilder { get; private set; }
private AudienceTarget(AudienceType audienceType, HashSet<string> values)
{
this.audienceType = audienceType;
this.valueBuilder = values;
}
public static AudienceTarget tag(HashSet<string> values)
{
return new AudienceTarget(AudienceType.tag,values).Check();
}
public static AudienceTarget tag_and(HashSet<string> values)
{
return new AudienceTarget(AudienceType.tag_and, values).Check();
}
public static AudienceTarget alias(HashSet<string> values)
{
return new AudienceTarget(AudienceType.alias, values).Check();
}
public static AudienceTarget segment(HashSet<string> values)
{
return new AudienceTarget(AudienceType.segment, values).Check();
}
public static AudienceTarget registrationId(HashSet<string> values)
{
return new AudienceTarget(AudienceType.registration_id, values).Check();
}
public AudienceTarget Check()
{
Preconditions.checkArgument(null != valueBuilder, "Target values should be set one at least.");
return this;
}
}
}
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Push.Audience
{
public enum AudienceType
{
tag,
tag_and,
alias,
segment,
registration_id
}
}
+46
View File
@@ -0,0 +1,46 @@
using Lskj.Push.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
namespace Lskj.Push.Push
{
public class MessageResult : BaseResult
{
public Int64 msg_id{get;set;}
public int sendno{ get; set; }
override public bool isResultOK()
{
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
{
return true;
}
return false;
}
public override string ToString()
{
return string.Format("sendno:{0},message_id:{1}", sendno, msg_id);
}
}
//"{\"sendno\":\"0\",\"msg_id\":\"1704649583\"}"
public class JpushSuccess
{
public string sendno;
public string msg_id;
}
public class JpushError
{
public JpushErrorObject error;
public long msg_id;
}
public class JpushErrorObject
{
public int code;
public String message;
}
}
+215
View File
@@ -0,0 +1,215 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Lskj.Push.Push.Audience;
using System.Diagnostics;
using Lskj.Push.Util;
namespace Lskj.Push.Push.Mode
{
public class Audience
{
private const String ALL = "all";
public string allAudience;
private void AddWithAudienceTarget(AudienceTarget target)
{
Debug.Assert(target != null && target.valueBuilder != null);
if (target != null && target.valueBuilder != null)
{
this.allAudience = null;
if (dictionary == null)
{
dictionary = new Dictionary<string, HashSet<string>>();
}
if (dictionary.ContainsKey(target.audienceType.ToString()))
{
HashSet<string> origin = dictionary[target.audienceType.ToString()];
foreach (var item in target.valueBuilder)
{
origin.Add(item);
}
}
else
{
dictionary.Add(target.audienceType.ToString(), target.valueBuilder);
}
}
}
public Dictionary<string, HashSet<string>> dictionary;
private Audience()
{
allAudience = ALL;
dictionary = null;
}
public static Audience all()
{
return new Audience() { allAudience = ALL, dictionary = null }.Check();
}
public static Audience s_tag(HashSet<string> values)
{
return new Audience().tag(values);
}
public static Audience s_tag(params string[] values)
{
return new Audience().tag(values);
}
public static Audience s_tag_and(HashSet<string> values)
{
return new Audience().tag_and(values);
}
public static Audience s_tag_and(params string[] values)
{
return new Audience().tag_and(values);
}
public static Audience s_alias(HashSet<string> values)
{
return new Audience().alias(values);
}
public static Audience s_alias(params string[] values)
{
return new Audience().alias(values);
}
public static Audience s_segment(HashSet<string> values)
{
return new Audience().segment(values);
}
public static Audience s_segment(params string[] values)
{
return new Audience().segment(values);
}
public static Audience s_registrationId(HashSet<string> values)
{
return new Audience().registrationId(values);
}
public static Audience s_registrationId(params string[] values)
{
return new Audience().registrationId(values);
}
public Audience tag(HashSet<string> values)
{
if (allAudience != null)
{
allAudience = null;
}
AudienceTarget target = AudienceTarget.tag(values);
AddWithAudienceTarget(target);
return this.Check();
}
public Audience tag(params string[] values)
{
if (allAudience != null)
{
allAudience = null;
}
var valueList = new HashSet<string>(values);
return tag(valueList);
}
public Audience tag_and(HashSet<string> values)
{
if (allAudience != null)
{
allAudience = null;
}
AudienceTarget target = AudienceTarget.tag_and(values);
this.allAudience = null;
if (dictionary == null)
{
dictionary = new Dictionary<string, HashSet<string>>();
}
if (dictionary.ContainsKey(target.audienceType.ToString()))
{
HashSet<string> origin = dictionary[target.audienceType.ToString()];
foreach (var item in values)
{
origin.Add(item);
}
}
else
{
dictionary.Add(target.audienceType.ToString(), values);
}
return this.Check();
}
public Audience tag_and(params string[] values)
{
if (allAudience != null)
{
allAudience = null;
}
HashSet<string> list = new HashSet<string>(values);
return tag_and(list);
}
public Audience alias(HashSet<string> values)
{
if (allAudience != null)
{
allAudience = null;
}
AddWithAudienceTarget( AudienceTarget.alias(values));
return this.Check();
}
public Audience alias(params string[] values)
{
if (allAudience != null)
{
allAudience = null;
}
return alias(new HashSet<string>(values));
}
public Audience segment(HashSet<string> values)
{
if (allAudience != null)
{
allAudience = null;
}
AddWithAudienceTarget(AudienceTarget.segment(values));
return this.Check();
}
public Audience segment(params string[] values)
{
if (allAudience != null)
{
allAudience = null;
}
return segment(new HashSet<string>(values));
}
public Audience registrationId(HashSet<string> values)
{
if (allAudience != null)
{
allAudience = null;
}
AddWithAudienceTarget(AudienceTarget.registrationId(values));
return this.Check();
}
public Audience registrationId(params string[] values)
{
if (allAudience != null)
{
allAudience = null;
}
return registrationId(new HashSet<string>(values));
}
public bool isAll(){
return allAudience != null;
}
public Audience Check()
{
Preconditions.checkArgument(!(isAll() && null != dictionary), "Since all is enabled, any platform should not be set.");
Preconditions.checkArgument(!(!isAll() && null == dictionary), "No any deviceType is set.");
return this;
}
}
}
+101
View File
@@ -0,0 +1,101 @@
using Lskj.Push.Util;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Push.Mode
{
public class Message
{
public String title{get;set;}
public String msg_content { get; set; }
public String content_type { get; set; }
[JsonProperty]
private Dictionary<string, object> extras { get; set; }
private Message()
{
}
private Message(String msgContent)
{
Preconditions.checkArgument(!(msgContent==null), "msgContent should be set");
this.title = null;
this.msg_content = msgContent;
this.content_type = null;
this.extras = null;
}
private Message(String msgContent, String title, String contentType)
{
Preconditions.checkArgument(!(msgContent == null), "msgContent should be set");
this.title = title;
this.msg_content = msgContent;
this.content_type = contentType;
}
public static Message content(string msgContent)
{
return new Message(msgContent).Check();
}
public Message setTitle(String title)
{
this.title = title;
return this;
}
public Message setContentType(String ContentType)
{
this.content_type = ContentType;
return this;
}
public Message AddExtras(string key, string value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
if (value != null)
{
extras.Add(key, value);
}
return this;
}
public Message AddExtras(string key, int value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
extras.Add(key, value);
return this;
}
public Message AddExtras(string key, bool value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
extras.Add(key, value);
return this;
}
public Message AddExtras(string key, object value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
extras.Add(key, value);
return this;
}
public Message Check()
{
Preconditions.checkArgument(!(msg_content==null), "msgContent should be set");
return this;
}
}
}
@@ -0,0 +1,129 @@
using Lskj.Push.Push.Notification;
using Lskj.Push.Util;
using Newtonsoft.Json;
// ------------------------------------------------------------------------------
// <autogenerated>
// This code was generated by a tool.
// Mono Runtime Version: 4.0.30319.1
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </autogenerated>
// ------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
namespace Lskj.Push.Push.Mode
{
public class Notification
{
public String alert{get;set;}
[JsonProperty(PropertyName = "ios")]
public IosNotification IosNotification { get; set; }
[JsonProperty(PropertyName = "android")]
public AndroidNotification AndroidNotification { get; set; }
[JsonProperty(PropertyName = "winphone")]
public WinphoneNotification WinphoneNotification { get; set; }
public Notification()
{
this.alert = null;
this.IosNotification = null;
this.AndroidNotification = null;
this.WinphoneNotification = null;
}
public Notification setAlert(string alert)
{
this.alert = alert;
return this;
}
public Notification setAndroid(AndroidNotification android)
{
this.AndroidNotification = android;
return this;
}
public Notification setIos(IosNotification ios)
{
this.IosNotification = ios;
return this;
}
public Notification setWinphone(WinphoneNotification winphone)
{
this.WinphoneNotification = winphone;
return this;
}
public static Notification android(String alert, String title)
{
var platformNotification = new AndroidNotification().setAlert(alert).setTitle(title);
var notificaiton = new Notification().setAlert(alert);
notificaiton.AndroidNotification = platformNotification;
return notificaiton;
}
public static Notification ios(String alert)
{
var iosNotification = new IosNotification().setAlert(alert);
var notification = new Notification().setAlert(alert);
notification.IosNotification = iosNotification;
return notification;
}
public static Notification ios_auto_badge()
{
var platformNotification = new IosNotification();
platformNotification.autoBadge();
var notificaiton = new Notification().setAlert("");;
notificaiton.IosNotification = platformNotification;
return notificaiton;
}
public static Notification ios_set_badge(int badge)
{
var platformNotification = new IosNotification();
platformNotification.setBadge(badge);
var notificaiton = new Notification();
notificaiton.IosNotification = platformNotification;
return notificaiton;
}
public static Notification ios_incr_badge(int badge)
{
var platformNotification = new IosNotification();
platformNotification.incrBadge(badge);
var notificaiton = new Notification();
notificaiton.IosNotification = platformNotification;
return notificaiton;
}
public static Notification winphone(String alert)
{
var platformNotification = new WinphoneNotification().setAlert(alert);
var notificaiton = new Notification().setAlert(alert);
notificaiton.WinphoneNotification = platformNotification;
return notificaiton;
}
public Notification Check()
{
Preconditions.checkArgument(!(isPlatformEmpty() && null == alert), "No notification payload is set.");
if (IosNotification!=null)
{
Preconditions.checkArgument(!(null==IosNotification.alert && null == alert), "No notification payload is set.");
}
if(AndroidNotification!=null)
{
Preconditions.checkArgument(!(null == AndroidNotification.alert && null == alert), "No notification payload is set.");
}
if (WinphoneNotification!=null)
{
Preconditions.checkArgument(!(null == WinphoneNotification.alert && null == alert), "No notification payload is set.");
}
return this;
}
private bool isPlatformEmpty()
{
return (IosNotification == null && AndroidNotification == null && WinphoneNotification == null);
}
}
}
+95
View File
@@ -0,0 +1,95 @@
using Lskj.Push.Util;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Push.Mode
{
public class Options
{
private const long NONE_TIME_TO_LIVE = -1;
public Options()
{
this.sendno = 0;
this.override_msg_id = 0;
this.time_to_live = NONE_TIME_TO_LIVE;
this.big_push_duration = 0;
this.apns_production = false;
}
public Options(int sendno,
long overrideMsgId,
long timeToLive,
int bigPushDuration,
bool apnsProduction=false)
{
this.sendno = sendno;
this.override_msg_id = overrideMsgId;
this.time_to_live = timeToLive;
this.big_push_duration = bigPushDuration;
this.apns_production = apnsProduction;
}
private int _sendno;
[DefaultValue(0)]
public int sendno
{
get
{
return _sendno;
}
set
{
Preconditions.checkArgument(value >= 0, "sendno should be greater than 0.");
_sendno = value;
}
}
private long _override_msg_id;
[DefaultValue(0)]
public long override_msg_id
{
get
{
return _override_msg_id;
}
set
{
Preconditions.checkArgument(value >= 0, "override_msg_id should be greater than 0.");
_override_msg_id = value;
}
}
private long _time_to_live;
[DefaultValue(NONE_TIME_TO_LIVE)]
public long time_to_live
{
get
{
return _time_to_live;
}
set
{
Preconditions.checkArgument(value >= NONE_TIME_TO_LIVE, "time_to_live should be greater than 0.");
_time_to_live = value;
}
}
private long _big_push_duration;
[DefaultValue(0)]
public long big_push_duration
{
get
{
return _big_push_duration;
}
set
{
Preconditions.checkArgument(value >= 0, "big_push_duration should be greater than 0.");
_big_push_duration = value;
}
}
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)]
public bool apns_production { get; set; }
}
}
+117
View File
@@ -0,0 +1,117 @@
using Lskj.Push.Common;
using Lskj.Push.Util;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Push.Mode
{
public class Platform
{
private const String ALL = "all";
[JsonProperty(PropertyName = "winphone")]
public string allPlatform{get;set;}
private HashSet<string> _deviceTypes;
public HashSet<string> deviceTypes
{
get
{
return _deviceTypes;
}
set
{
if (value != null)
{
allPlatform = null;
}
_deviceTypes = value;
}
}
private Platform()
{
allPlatform = ALL;
deviceTypes = null;
}
private Platform(bool all, HashSet<string> deviceTypes)
{
//用来判断all=true时deviceTypes必须为空,反之当all=false时deviceTypes有值,不然json序列化会出错
Debug.Assert(all && deviceTypes == null || !all && deviceTypes != null);
if (all)
{
allPlatform = ALL;
}
this.deviceTypes = deviceTypes;
}
public static Platform all()
{
return new Platform(true, null).Check();
}
public static Platform ios()
{
HashSet<string> types = new HashSet<string>();
types.Add(DeviceType.ios.ToString());
return new Platform(false,types).Check();
}
public static Platform android()
{
HashSet<string> types = new HashSet<string>();
types.Add(DeviceType.android.ToString());
return new Platform(false, types).Check();
}
public static Platform winphone()
{
HashSet<string> types = new HashSet<string>();
types.Add(DeviceType.winphone.ToString());
return new Platform(false, types).Check();
}
public static Platform android_ios()
{
HashSet<string> types = new HashSet<string>();
types.Add(DeviceType.android.ToString());
types.Add(DeviceType.ios.ToString());
return new Platform(false, types).Check();
}
public static Platform android_winphone()
{
HashSet<string> types = new HashSet<string>();
types.Add(DeviceType.android.ToString());
types.Add(DeviceType.winphone.ToString());
return new Platform(false, types).Check();
}
public static Platform ios_winphone()
{
HashSet<string> types = new HashSet<string>();
types.Add(DeviceType.ios.ToString());
types.Add(DeviceType.winphone.ToString());
return new Platform(false, types).Check();
}
public bool isAll()
{
return allPlatform != null;
}
public void setAll(bool all)
{
if (all)
{
allPlatform = ALL;
}
else
{
allPlatform = null;
}
}
public Platform Check()
{
Preconditions.checkArgument(!(isAll() && null != deviceTypes), "Since all is enabled, any platform should not be set.");
Preconditions.checkArgument(!(!isAll() && null == deviceTypes), "No any deviceType is set.");
return this;
}
}
}
@@ -0,0 +1,214 @@
using Lskj.Push.Common;
using Lskj.Push.Push.Notification;
using Lskj.Push.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Push.Mode
{
public class PushPayload
{
private JsonSerializerSettings jSetting;
private const String PLATFORM = "platform";
private const String AUDIENCE = "audience";
private const String NOTIFICATION = "notification";
private const String MESSAGE = "message";
private const String OPTIONS = "options";
private const int MAX_GLOBAL_ENTITY_LENGTH = 1200; // Definition acording to JPush Docs
private const int MAX_IOS_PAYLOAD_LENGTH = 220; // Definition acording to JPush Docs
//serializaiton property
[JsonConverter(typeof(PlatformConverter))]
public Platform platform{get;set;}
[JsonConverter(typeof(AudienceConverter))]
public Audience audience{get;set;}
public Notification notification { get; set; }
public Message message { get; set; }
public Options options { get; set; }
//construct
public PushPayload()
{
platform = null;
audience = null;
notification = null;
message = null;
options = new Options();
jSetting = new JsonSerializerSettings();
jSetting.NullValueHandling = NullValueHandling.Ignore;
jSetting.DefaultValueHandling = DefaultValueHandling.Ignore;
}
public PushPayload(Platform platform, Audience audience, Notification notification, Message message = null, Options options = null)
{
Debug.Assert(platform != null);
Debug.Assert(audience != null);
Debug.Assert(notification != null || message != null);
this.platform = platform;
this.audience = audience;
this.notification = notification;
this.message = message;
this.options = options;
jSetting = new JsonSerializerSettings();
jSetting.NullValueHandling = NullValueHandling.Ignore;
jSetting.DefaultValueHandling = DefaultValueHandling.Ignore;
}
/**
* The shortcut of building a simple alert notification object to all platforms and all audiences
*/
public static PushPayload AlertAll(String alert)
{
return new PushPayload(Platform.all(),
Audience.all(),
new Notification().setAlert(alert),
null,
new Options());
}
//* The shortcut of building a simple message object to all platforms and all audiences
//*/
public static PushPayload MessageAll(String msgContent)
{
return new PushPayload( Platform.all(),
Audience.all(),
null,
Message.content(msgContent),
new Options());
}
public static PushPayload FromJSON(String payloadString)
{
try
{
var jSetting = new JsonSerializerSettings();
jSetting.NullValueHandling = NullValueHandling.Ignore;
jSetting.DefaultValueHandling = DefaultValueHandling.Ignore;
var jsonObject = JsonConvert.DeserializeObject<PushPayload>(payloadString, jSetting);
return jsonObject.Check();
}
catch (Exception e)
{
Console.WriteLine("JSON to PushPayLoad occur error:" + e.Message);
return null;
}
}
public void ResetOptionsApnsProduction(bool apnsProduction)
{
if (this.options == null)
{
this.options = new Options();
}
this.options.apns_production = apnsProduction;
}
public void ResetOptionsTimeToLive(long timeToLive)
{
if (this.options == null)
{
this.options = new Options();
}
this.options.time_to_live = timeToLive;
}
public int GetSendno()
{
if (this.options != null)
return this.options.sendno;
return 0;
}
public bool IsGlobalExceedLength()
{
int messageLength = 0;
if (message!= null)
{
var messageJson = JsonConvert.SerializeObject(this.message, jSetting);
messageLength += UTF8Encoding.UTF8.GetBytes(messageJson).Length;
}
if (this.notification == null)
{
return messageLength > MAX_GLOBAL_ENTITY_LENGTH;
}
else
{
var notificationJson = JsonConvert.SerializeObject(this.notification);
if (notificationJson != null)
{
messageLength += UTF8Encoding.UTF8.GetBytes(notificationJson).Length;
}
return messageLength > MAX_GLOBAL_ENTITY_LENGTH;
}
}
public bool IsIosExceedLength()
{
if (this.notification != null)
{
if (this.notification.IosNotification != null)
{
var iosJson = JsonConvert.SerializeObject(this.notification.IosNotification, jSetting);
if (iosJson != null)
{
return UTF8Encoding.UTF8.GetBytes(iosJson).Length > MAX_IOS_PAYLOAD_LENGTH;
}
}
else
{
if (!(this.notification.alert==null))
{
string jsonText;
using (StringWriter sw = new StringWriter())
{
JsonWriter writer = new JsonTextWriter(sw);
writer.WriteValue(this.notification.alert);
writer.Flush();
jsonText = sw.GetStringBuilder().ToString();
}
return UTF8Encoding.UTF8.GetBytes(jsonText).Length > MAX_IOS_PAYLOAD_LENGTH;
}
else
{
// No iOS Payload
}
}
}
return false;
}
public string ToJson()
{
return JsonConvert.SerializeObject(this, jSetting);
}
public PushPayload Check()
{
Preconditions.checkArgument(!(null == audience || null == platform), "audience and platform both should be set.");
Preconditions.checkArgument(!(null == notification && null == message), "notification or message should be set at least one.");
if (audience!=null)
{
audience.Check();
}
if (platform != null)
{
platform.Check();
}
if (message != null)
{
message.Check();
}
if (notification != null)
{
notification.Check();
}
return this;
}
}
}
+14
View File
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Lskj.Push.Push.Mode
{
public class PushUserObj
{
public string username { get; set; }
public string password { get; set; }
public string nickname { get; set; }
}
}
@@ -0,0 +1,84 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Push.Notification
{
public class AndroidNotification:PlatformNotification
{
public const String NOTIFICATION_ANDROID = "android";
private const String TITLE = "title";
private const String BUILDER_ID = "builder_id";
[JsonProperty]
public String title{get;private set;}
[JsonProperty]
public int builder_id { get; private set; }
public AndroidNotification():base()
{
this.title = null;
this.builder_id = 0;
}
public AndroidNotification setTitle(string title)
{
this.title = title;
return this;
}
public AndroidNotification setBuilderID(int builder_id)
{
this.builder_id = builder_id;
return this;
}
public AndroidNotification setAlert(String alert)
{
this.alert = alert;
return this;
}
public AndroidNotification AddExtra(string key, string value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
if (value != null)
{
extras.Add(key, value);
}
return this;
}
public AndroidNotification AddExtra(string key, int value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
extras.Add(key, value);
return this;
}
public AndroidNotification AddExtra(string key, bool value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
extras.Add(key, value);
return this;
}
public AndroidNotification AddExtra(string key, object value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
extras.Add(key, value);
return this;
}
}
}
@@ -0,0 +1,166 @@
using Lskj.Push.Common;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Push.Notification
{
public class IosNotification : PlatformNotification
{
public const String NOTIFICATION_IOS = "ios";
private const String DEFAULT_SOUND = "";
private const String DEFAULT_BADGE = "+1";
private const String BADGE = "badge";
private const String SOUND = "sound";
private const String CONTENT_AVAILABLE = "content-available";
private const String CATEGORY = "category";
private const String ALERT_VALID_BADGE = "Badge number should be 0~99999, "
+ "and badgeDisabled property must be false";
private const String SOUNd_VALID_BADGE = "Sound should not be null or empty, "
+ "and disableSound property must be false";
private bool soundDisabled;
private bool badgeDisabled;
[JsonProperty]
public String sound { get;private set; }
[JsonProperty]
public String badge { get; private set; }
[JsonProperty(PropertyName = "content-available")]
public bool contentAvailable { get; private set; }
[JsonProperty]
public String category { get; private set; }
public IosNotification()
{
base.alert = null;
base.extras = null;
this.soundDisabled = false;
this.badgeDisabled = false;
this.contentAvailable = false;
this.category = null;
this.badge = DEFAULT_BADGE;
this.sound = DEFAULT_SOUND;
}
public IosNotification disableSound()
{
this.soundDisabled = true;
this.sound = null;
return this;
}
public IosNotification disableBadge()
{
this.badgeDisabled = true;
this.badge = null;
return this;
}
public IosNotification setSound(String sound)
{
if ((sound ==null) || soundDisabled)
{
Console.WriteLine(SOUNd_VALID_BADGE);
return this;
}
this.sound = sound;
return this;
}
public IosNotification setBadge(int badge)
{
if (!ServiceHelper.isValidIntBadge(Math.Abs(badge)) || badgeDisabled)
{
Console.WriteLine(ALERT_VALID_BADGE);
return this;
}
this.badge = badge.ToString();
return this;
}
public IosNotification autoBadge()
{
return incrBadge(1);
}
public IosNotification incrBadge(int badge)
{
if (!ServiceHelper.isValidIntBadge(Math.Abs(badge))|| badgeDisabled)
{
Console.WriteLine(ALERT_VALID_BADGE);
return this;
}
if (badge >= 0)
{
this.badge = "+" + badge;
}
else
{
this.badge = "" + badge;
}
return this;
}
public IosNotification setAlert(String alert)
{
this.alert = alert;
return this;
}
public IosNotification setContentAvailable(bool contentAvailable)
{
this.contentAvailable = contentAvailable;
return this;
}
public IosNotification setCategory(String category)
{
this.category = category;
return this;
}
public IosNotification AddExtra(string key, string value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
if (value !=null)
{
extras.Add(key, value);
}
return this;
}
public IosNotification AddExtra(string key, int value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
extras.Add(key, value);
return this;
}
public IosNotification AddExtra(string key, bool value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
extras.Add(key, value);
return this;
}
public IosNotification AddExtra(string key, object value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
extras.Add(key, value);
return this;
}
}
}
@@ -0,0 +1,29 @@
using Lskj.Push.Push.Mode;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Push.Notification
{
public abstract class PlatformNotification
{
public const String ALERT = "alert";
private const String EXTRAS = "extras";
[JsonProperty]
public String alert{get;protected set;}
[JsonProperty]
public Dictionary<String, object> extras { get; protected set; }
public PlatformNotification()
{
this.alert = null;
this.extras = null;
}
}
}
@@ -0,0 +1,71 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Push.Notification
{
public class WinphoneNotification : PlatformNotification
{
[JsonProperty]
private String title;
[JsonProperty(PropertyName = "_open_page")]
public String openPage;
public WinphoneNotification():base()
{
this.title = null;
this.openPage = null;
}
public WinphoneNotification setAlert(String alert)
{
this.alert = alert;
return this;
}
public WinphoneNotification setOpenPage(String openPage)
{
this.openPage = openPage;
return this;
}
public WinphoneNotification setTitle(String title)
{
this.title = title;
return this;
}
public WinphoneNotification AddExtra(string key, string value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
if (value!=null)
{
extras.Add(key, value);
}
return this;
}
public WinphoneNotification AddExtra(string key, int value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
extras.Add(key, value);
return this;
}
public WinphoneNotification AddExtra(string key, bool value)
{
if (extras == null)
{
extras = new Dictionary<string, object>();
}
extras.Add(key, value);
return this;
}
}
}
+65
View File
@@ -0,0 +1,65 @@
using Lskj.Push.Common;
using Lskj.Push.Push.Mode;
using Lskj.Push.Util;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Push
{
internal class PushClient:BaseHttpClient
{
private const String HOST_NAME_SSL = "https://api.jpush.cn";
private const String PUSH_PATH = "/v3/push";
private String appKey;
private String masterSecret;
public PushClient(String appKey,String masterSecret)
{
this.appKey = appKey;
this.masterSecret = masterSecret;
}
public MessageResult sendPush(PushPayload payload)
{
Preconditions.checkArgument(payload != null, "pushPayload should not be empty");
payload.Check();
String payloadJson = payload.ToJson();
return sendPush(payloadJson);
}
public MessageResult sendPush(string payloadString)
{
Preconditions.checkArgument(!string.IsNullOrEmpty(payloadString), "payloadString should not be empty");
String url = HOST_NAME_SSL;
url += PUSH_PATH;
ResponseWrapper result = sendPost(url, Authorization(), payloadString);
MessageResult messResult = new MessageResult();
messResult.ResponseResult = result;
JpushSuccess jpushSuccess = JsonConvert.DeserializeObject<JpushSuccess>(result.responseContent);
messResult.sendno = int.Parse(jpushSuccess.sendno);
//messResult.msg_id = int.Parse(jpushSuccess.msg_id);
messResult.msg_id = Convert.ToInt64(jpushSuccess.msg_id);
return messResult;
}
private String Authorization(){
Debug.Assert(!string.IsNullOrEmpty(this.appKey));
Debug.Assert(!string.IsNullOrEmpty(this.masterSecret));
String origin=this.appKey+":"+this.masterSecret;
return Base64.getBase64Encode(origin);
}
}
enum MsgTypeEnum
{
NOTIFICATIFY = 1,
COUSTOM_MESSAGE =2
}
}
@@ -0,0 +1,77 @@
using Lskj.Push.Common;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Report
{
public class MessagesResult : BaseResult
{
public List<Message> messages = new List<Message>();
public static MessagesResult fromResponse(ResponseWrapper responseWrapper)
{
MessagesResult receivedsResult = new MessagesResult();
if (responseWrapper.responseCode==HttpStatusCode.OK)
{
receivedsResult.messages = JsonConvert.DeserializeObject<List<Message>>(responseWrapper.responseContent);
}
receivedsResult.ResponseResult = responseWrapper;
return receivedsResult;
}
public override bool isResultOK()
{
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
{
return true;
}
return false;
}
public class Message
{
public Message()
{
msg_id = 0;
android = null;
ios = null;
}
public long msg_id;
public Android android;
public Ios ios;
}
public class Android
{
public Android()
{
received = 0;
target = 0;
online_push = 0;
click = 0;
}
public int received;
public int target;
public int online_push;
public int click;
}
public class Ios
{
public Ios()
{
apns_sent = 0;
apns_target = 0;
click = 0;
}
public int apns_sent;
public int apns_target;
public int click;
}
}
}
@@ -0,0 +1,55 @@
using Lskj.Push.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Report
{
public class ReceivedResult : BaseResult
{
private List<Received> receivedList = new List<Received>();
public List<Received> ReceivedList
{
get { return receivedList; }
set { receivedList = value; }
}
public class Received {
public long msg_id;
public String android_received;
public String ios_apns_sent;
}
public override bool isResultOK()
{
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
{
return true;
}
return false;
}
public HttpStatusCode getErrorCode()
{
if (null != ResponseResult)
{
return ResponseResult.responseCode;
}
return 0;
}
public string getErrorMessage()
{
if (null != ResponseResult)
{
return ResponseResult.exceptionString;
}
return "";
}
}
}
+117
View File
@@ -0,0 +1,117 @@
using Lskj.Push.Common;
using Lskj.Push.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Lskj.Push.Report
{
class ReportClient:BaseHttpClient
{
private const String REPORT_HOST_NAME = "https://report.jpush.cn";
private const String REPORT_RECEIVE_PATH = "/v2/received";
private const String REPORT_RECEIVE_PATH_V3 = "/v3/received";
private const String REPORT_USER_PATH = "/v3/users";
private String appKey;
private String masterSecret;
public ReportClient(String appKey, String masterSecret)
{
this.appKey = appKey;
this.masterSecret = masterSecret;
}
public ReceivedResult getReceiveds(String msg_ids)
{
checkMsgids(msg_ids);
return getReceiveds_common(msg_ids, REPORT_RECEIVE_PATH);
}
public ReceivedResult getReceiveds_v3(String msg_ids)
{
checkMsgids(msg_ids);
return getReceiveds_common(msg_ids, REPORT_RECEIVE_PATH_V3);
}
public UsersResult getUsers(TimeUnit timeUnit, String start, int duration)
{
String url = REPORT_HOST_NAME + REPORT_USER_PATH
+ "?time_unit=" + timeUnit.ToString()
+ "&start=" + start + "&duration=" + duration;
String auth = Base64.getBase64Encode(this.appKey + ":" + this.masterSecret);
ResponseWrapper response = this.sendGet(url, auth, null);
return UsersResult.fromResponse(response);
}
public MessagesResult getReportMessages(params String[] msgIds)
{
return getReportMessages(StringUtil.arrayToString(msgIds));
}
public String checkMsgids(String msgIds)
{
if (string.IsNullOrEmpty(msgIds)) {
throw new ArgumentException("msgIds param is required.");
}
Regex reg = new Regex(@"[^0-9, ]");
if(reg.IsMatch(msgIds))
{
throw new ArgumentException("msgIds param format is incorrect. "
+ "It should be msg_id (number) which response from JPush Push API. "
+ "If there are many, use ',' as interval. ");
}
msgIds = msgIds.Trim();
if (msgIds.EndsWith(",")) {
msgIds = msgIds.Substring(0, msgIds.Length - 1);
}
String[] splits = msgIds.Split(',');
List<string> list = new List<string>();
try {
foreach (String s in splits) {
string trim = s.Trim();
if (!string.IsNullOrEmpty(trim))
{
int.Parse(trim);
list.Add(trim);
}
}
return StringUtil.arrayToString(list.ToArray());
} catch (Exception) {
throw new Exception("Every msg_id should be valid Integer number which splits by ','");
}
}
private ReceivedResult getReceiveds_common(String msg_ids, string path)
{
String url = REPORT_HOST_NAME + path + "?msg_ids=" + msg_ids;
String auth = Base64.getBase64Encode(this.appKey + ":" + this.masterSecret);
ResponseWrapper rsp = this.sendGet(url, auth, null);
ReceivedResult result = new ReceivedResult();
List<ReceivedResult.Received> list = new List<ReceivedResult.Received>();
Console.WriteLine("recieve content==" + rsp.responseContent);
if (rsp.responseCode == System.Net.HttpStatusCode.OK)
{
list = (List<ReceivedResult.Received>)JsonTool.JsonToObject(rsp.responseContent, list);
String content = rsp.responseContent;
}
result.ResponseResult = rsp;
result.ReceivedList = list;
return result;
}
private MessagesResult getReportMessages(String msgIds)
{
String checkMsgId = checkMsgids(msgIds);
String url = REPORT_HOST_NAME + REPORT_RECEIVE_PATH + "?msg_ids=" + checkMsgId;
String auth = Base64.getBase64Encode(this.appKey + ":" + this.masterSecret);
ResponseWrapper response = this.sendGet(url, auth, null);
return MessagesResult.fromResponse(response);
}
}
}
+89
View File
@@ -0,0 +1,89 @@
using Lskj.Push.Common;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Report
{
public class UsersResult : BaseResult
{
public TimeUnit time_unit;
public String start;
public int duration;
public UsersResult()
{
time_unit = TimeUnit.DAY;
start = null;
duration = 0;
}
public List<User> items = new List<User>();
public static UsersResult fromResponse(ResponseWrapper responseWrapper)
{
UsersResult usersResult = new UsersResult();
if (responseWrapper.isServerResponse()) {
usersResult = JsonConvert.DeserializeObject<UsersResult> (responseWrapper.responseContent);
}
usersResult.ResponseResult=responseWrapper;
return usersResult;
}
public override bool isResultOK()
{
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
{
return true;
}
return false;
}
public class User
{
public String time;
public Android android;
public Ios ios;
public User()
{
time = null;
android = null;
ios = null;
}
}
public class Android
{
[JsonProperty(PropertyName = "new")]
public long add;
public int online;
public int active;
public Android()
{
add = 0;
online = 0;
active = 0;
}
}
public class Ios
{
[JsonProperty(PropertyName = "new")]
public long add;
public int online;
public int active;
public Ios()
{
add = 0;
online = 0;
active = 0;
}
}
}
}
+18
View File
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Util
{
class Base64
{
public static String getBase64Encode(String str)
{
byte[] bytes = Encoding.Default.GetBytes(str);
//
return Convert.ToBase64String(bytes);
}
}
}
+88
View File
@@ -0,0 +1,88 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Diagnostics;
using Lskj.Push.Report;
namespace Lskj.Push.Util
{
public class JsonTool
{
// 从一个对象信息生成Json串
public static string ObjectToJson(object obj)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
MemoryStream stream = new MemoryStream();
serializer.WriteObject(stream, obj);
byte[] dataBytes = new byte[stream.Length];
stream.Position = 0;
stream.Read(dataBytes, 0, (int)stream.Length);
return Encoding.UTF8.GetString(dataBytes).Replace("\\","");
}
// 从一个Json串生成对象信息
public static object JsonToObject(string jsonString, object obj)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
MemoryStream mStream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
return serializer.ReadObject(mStream);
}
// 从一个对象信息生成Json串
public static string DictionaryToJson(Dictionary<String, Object> dict)
{
StringBuilder json = new StringBuilder();
foreach (KeyValuePair<String, Object> pair in dict)
{
json.Append("\"").Append(pair.Key).Append("\"").Append(":").Append(ValueToJson(pair.Value)).Append(",");
}
//Console.WriteLine("json String ******"+json);
if (json.Length > 0)
{
json.Remove(json.Length -1, 1);
}
json.Append("}");
json.Insert(0, "{");
return json.ToString();
}
public static List<ReceivedResult.Received> JsonList(string jsonString)
{
JavaScriptSerializer Serializer = new JavaScriptSerializer();
List<ReceivedResult.Received> jsonclassList = Serializer.Deserialize<List<ReceivedResult.Received>>(jsonString);
return jsonclassList;
}
//从dictionary 的value中解析出字符串
private static string ValueToJson(object value)
{
Type type = value.GetType();
if(type==typeof(int)){
return value.ToString();
}else if(type==typeof(string)){
return "\""+value+"\"";
}else if(type==typeof(List<int>)||type==typeof(List<string>)){
return ObjectToJson(value);
}else if(type==typeof(Dictionary<string,object>)){
return JsonTool.DictionaryToJson((Dictionary<string, object>)value);
}
else{
Debug.WriteLine("Type in Dictionary is error!");
return "type erro";
}
}
}
}
+54
View File
@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
namespace Lskj.Push.Util
{
class Md5
{
public static String getMD5Hash(String str)
{
// MD5 md5 = new MD5CryptoServiceProvider();
//byte[] res = md5.ComputeHash(Encoding.Default.GetBytes(str), 0, str.Length);
//char[] temp = new char[res.Length];
//System.Array.Copy(res, temp, res.Length);
//return new String(temp);
// 创建MD5类的默认实例:MD5CryptoServiceProvider
MD5 md5 = MD5.Create();
byte[] bs = Encoding.UTF8.GetBytes(str);
byte[] hs = md5.ComputeHash(bs);
StringBuilder sb = new StringBuilder();
foreach (byte b in hs)
{
// 以十六进制格式格式化
sb.Append(b.ToString("x2"));
}
return sb.ToString();
}
}
}
+26
View File
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lskj.Push.Util
{
class Preconditions
{
public static void checkArgument(bool expression)
{
if (!expression)
{
throw new ArgumentNullException();
}
}
public static void checkArgument(bool expression, object errorMessage)
{
if (!expression)
{
throw new ArgumentException(errorMessage.ToString());
}
}
}
}
+57
View File
@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Lskj.Push.Util
{
class StringUtil
{
public bool IsNumber(String strNumber)
{
Regex objNotNumberPattern=new Regex("[^0-9.-]");
Regex objTwoDotPattern=new Regex("[0-9]*[.][0-9]*[.][0-9]*");
Regex objTwoMinusPattern=new Regex("[0-9]*[-][0-9]*[-][0-9]*");
String strValidRealPattern="^([-]|[.]|[-.]|[0-9])[0-9]*[.]*[0-9]+$";
String strValidIntegerPattern="^([-]|[0-9])[0-9]*$";
Regex objNumberPattern =new Regex("(" + strValidRealPattern +")|(" + strValidIntegerPattern + ")");
return !objNotNumberPattern.IsMatch(strNumber) &&
!objTwoDotPattern.IsMatch(strNumber) &&
!objTwoMinusPattern.IsMatch(strNumber) &&
objNumberPattern.IsMatch(strNumber);
}
public static bool IsNumeric(string value)
{
return Regex.IsMatch(value, @"^[+-]?\d*[.]?\d*$");
}
public static bool IsInt(string value)
{
return Regex.IsMatch(value, @"^[+-]?\d*$");
}
public static bool IsUnsign(string value)
{
return Regex.IsMatch(value, @"^\d*[.]?\d*$");
}
public static String arrayToString(String[] values)
{
if (null == values) return "";
StringBuilder buffer = new StringBuilder(values.Length);
for (int i = 0; i < values.Length; i++)
{
buffer.Append(values[i]).Append(",");
}
if (buffer.Length > 0)
{
return buffer.ToString().Substring(0, buffer.Length - 1);
}
return "";
}
}
}
+15
View File
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>