调用Windows phone推送通知服务的Java客户端框架/API
有人知道是否有Java客户端框架/API可以调用Windows phone推送通知服务吗?我知道有一个项目是专门针对苹果PNS的。 我正在寻找类似的东西,但特定于Windows phone调用Windows phone推送通知服务的Java客户端框架/API,java,windows-phone,Java,Windows Phone,有人知道是否有Java客户端框架/API可以调用Windows phone推送通知服务吗?我知道有一个项目是专门针对苹果PNS的。 我正在寻找类似的东西,但特定于Windows phone 有什么帮助吗?Java mpns似乎很接近您想要的 我已经开发了一个带有Spring和Apache Commons HTTP客户端的解决方案,用于使用WNS(Windows通知推送服务)发送原始消息 在pom.xml中插入此依赖项: <dependency> <groupId>
有什么帮助吗?Java mpns似乎很接近您想要的
我已经开发了一个带有Spring和Apache Commons HTTP客户端的解决方案,用于使用WNS(Windows通知推送服务)发送原始消息 在pom.xml中插入此依赖项:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.12</version>
</dependency>
HttpClientFactory(如下所示)用于在发送消息时创建新的客户端。如果重复使用同一个HttpClient发送消息,则WNS将在发送第二条消息后超时。我不知道为什么会发生这种情况,但当我停止重用客户端时,问题就解决了
@Service
public class HttpClientFactory {
private static final int TIMEOUT = 20 * 1000;
public HttpClient create() {
SystemDefaultHttpClient httpClient = new SystemDefaultHttpClient();
httpClient.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, TIMEOUT);
httpClient.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT, TIMEOUT);
httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(NumberUtils.INTEGER_ZERO, false));
return httpClient;
}
}
这是一个基类,如您所愿,您可以将所有代码下拉到WindowsPushNotificationMediator
public abstract class AbstractCloudMediator {
private static final Logger LOG = Logger.getLogger(AbstractCloudMediator.class.getSimpleName());
@Autowired
private HttpClientFactory clientFactory;
@Autowired
protected ObjectMapper mapper;
public abstract boolean sendMessage(Jogador destinatario, Action mensagem);
protected String postToString(HttpPost post) throws IOException, ClientProtocolException {
HttpResponse response = executeMethod(post);
return responseToString(response);
}
protected String responseToString(HttpResponse response) throws IOException {
InputStream conteudoResposta = response.getEntity().getContent();
try {
return IOUtils.toString(conteudoResposta);
} finally {
IOUtils.closeQuietly(conteudoResposta);
}
}
protected HttpResponse executeMethod(HttpPost post) throws IOException, ClientProtocolException {
LOG.info("posting to... " + post);
return clientFactory.create().execute(post);
}
}
下一个类应该完成主要工作,但是记住创建一个cloudMessagingDAO
来检索和存储您的访问令牌。
您应该为另一个包含客户端URL的类替换类Jogador
,该类用于向Windows Phone设备发送消息
@Service(SharedConstants.WINDOWS_CLOUD_BEAN)
public class WindowsPushNotificationMediator extends AbstractCloudMediator { // NO_UCD (test only)
private static final Logger LOG = Logger.getLogger(WindowsPushNotificationMediator.class.getName());
private static final String KEY_ACCESS_TOKEN = "access_token";
private static final String KEY_TOKEN_TYPE = "token_type";
@Resource(name = "authenticateWNSHeaders")
private Map<String, String> authenticateWNSHeaders;
@Resource(name = "authenticateWNSPostParams")
private Map<String, String> authenticateWNSPostParams;
@Resource(name = "sendMessageWNSHeaders")
private Map<String, String> sendMessageWNSHeaders;
@Autowired
@Qualifier("authenticateUrlPostWNS")
private String authenticateUrlPostWNS;
@Autowired
private CloudMessagingDAO cloudMessagingDAO;
private OAuthToken oathToken;
@Override
public boolean sendMessage(Jogador destinatario, Action mensagem) {
try {
OAuthToken token = getToken();
String jsonString = mapper.writeValueAsString(mensagem);
StringEntity entity = new StringEntity(jsonString, Consts.UTF_8);
return sendMessage(destinatario, entity, token);
} catch (IOException e) {
LOG.log(Level.SEVERE, e.getMessage(), e);
throw new RuntimeException(e);
}
}
private boolean sendMessage(Jogador destinatario, HttpEntity entity, OAuthToken token) throws IOException {
HttpPost post = new HttpPost(destinatario.getCloudMessagingInfo());// this is the client url
post.addHeader("Authorization", token.getAuthorization());
addPostHeaders(post, sendMessageWNSHeaders);
post.setEntity(entity);
HttpResponse response = executeMethod(post);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
return sendMessage(destinatario, entity, getNewToken());
}
Header[] allHeaders = response.getAllHeaders();
StringBuilder builder = new StringBuilder();
for (Header header : allHeaders) {
builder.append(header.getName() + ": " + header.getValue());
builder.append('\n');
}
LOG.info(builder.toString());
return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
}
private void addPostHeaders(HttpPost post, Map<String, String> postHeaders) {
for (String key : postHeaders.keySet()) {
post.addHeader(key, postHeaders.get(key));
}
}
private OAuthToken getToken() throws IOException {
if (oathToken == null) {
//You should store your access token, so you can reuse it until it expires
String token = cloudMessagingDAO.getValue(KEY_ACCESS_TOKEN);
String tokenType = cloudMessagingDAO.getValue(KEY_TOKEN_TYPE);
if (StringUtils.isNotBlank(token) && StringUtils.isNotBlank(tokenType)) {
return oathToken = new OAuthToken(token, tokenType);
}
return getNewToken();
}
return oathToken;
}
private OAuthToken getNewToken() throws IOException {
HttpPost post = new HttpPost(authenticateUrlPostWNS);
addPostHeaders(post, authenticateWNSHeaders);
List<NameValuePair> params = new ArrayList<>();
for (String key : authenticateWNSPostParams.keySet()) {
params.add(new BasicNameValuePair(key, authenticateWNSPostParams.get(key)));
}
post.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = executeMethod(post);
String conteudo = responseToString(response);
LOG.info(conteudo);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
throw new NegocioException("Falha ao autenticar no serviço: " + conteudo);
}
@SuppressWarnings("unchecked")
Map<String, String> resultMap = mapper.readValue(conteudo, HashMap.class);
cloudMessagingDAO.setValues(resultMap);
return oathToken = new OAuthToken(resultMap.get(KEY_ACCESS_TOKEN), resultMap.get(KEY_TOKEN_TYPE));
}
}
@Service(SharedConstants.WINDOWS\u CLOUD\u BEAN)
公共类WindowsPushNotificationMediator扩展了AbstractCloudMediator{//NO\uUCD(仅限测试)
私有静态最终记录器LOG=Logger.getLogger(WindowsPushNotificationMediator.class.getName());
私有静态最终字符串KEY\u ACCESS\u TOKEN=“ACCESS\u TOKEN”;
私有静态最终字符串密钥\u令牌\u类型=“令牌\u类型”;
@资源(name=“authenticateWNSHeaders”)
私人地图认证Wnsheaders;
@资源(name=“authenticateWNSPostParams”)
私有地图验证WnsPostParams;
@资源(name=“sendMessageWNSHeaders”)
私人地图发送者;
@自动连线
@限定符(“authenticateUrlPostWNS”)
私有字符串authenticateUrlPostWNS;
@自动连线
私有CloudMessagingDAO CloudMessagingDAO;
私有OAuthToken oathToken;
@凌驾
公共布尔发送消息(Jogador destinatario,Action mensagem){
试一试{
OAuthToken令牌=getToken();
字符串jsonString=mapper.writeValueAsString(mensage);
StringEntity=新的StringEntity(jsonString,Consts.UTF_8);
返回sendMessage(目的地、实体、令牌);
}捕获(IOE异常){
LOG.LOG(Level.SEVERE,e.getMessage(),e);
抛出新的运行时异常(e);
}
}
私有布尔sendMessage(Jogador destinatario、HttpEntity、OAuthToken令牌)引发IOException{
HttpPost=newhttppost(destinatario.getcloudmessagininfo());//这是客户端url
post.addHeader(“Authorization”,token.getAuthorization());
addPostHeaders(post、sendMessageWNSHeaders);
后设实体(实体);
HttpResponse响应=执行方法(post);
if(response.getStatusLine().getStatusCode()==HttpStatus.SC\u未经授权){
返回sendMessage(destinatario,entity,getNewToken());
}
Header[]allHeaders=response.getAllHeaders();
StringBuilder=新的StringBuilder();
用于(标题:所有标题){
append(header.getName()+“:”+header.getValue());
builder.append('\n');
}
LOG.info(builder.toString());
返回响应。getStatusLine().getStatusCode()==HttpStatus.SC\u OK;
}
私有void addPostHeaders(HttpPost、Map postHeaders){
for(字符串键:postHeaders.keySet()){
post.addHeader(键,postHeaders.get(键));
}
}
私有OAuthToken getToken()引发IOException{
如果(oathToken==null){
//您应该存储您的访问令牌,以便在它过期之前可以重用它
String token=cloudMessagingDAO.getValue(KEY\u ACCESS\u token);
String-tokenType=cloudMessagingDAO.getValue(KEY\u-TOKEN\u-TYPE);
if(StringUtils.isNotBlank(令牌)和&StringUtils.isNotBlank(令牌类型)){
return-oahtoken=新的OAuthToken(token,tokenType);
}
返回getNewToken();
}
返回燕麦;
}
私有OAuthToken getNewToken()引发IOException{
HttpPost=新的HttpPost(authenticateUrlPostWNS);
AddPostHeader(post、authenticateWNSHeaders);
List params=new ArrayList();
for(字符串键:authenticateWNSPostParams.keySet()){
add(新的BasicNameValuePair(key,authenticateWNSPostParams.get(key));
}
post.setEntity(新的UrlEncodedFormEntity(params));
HttpResponse响应=执行方法(post);
字符串conteudo=响应字符串(响应);
日志信息(conteudo);
if(response.getStatusLine().getStatusCode()!=HttpStatus.SC\u OK){
抛出新的NegocioException(“Falha ao autenticar no serviço:”+conteudo);
}
@抑制警告(“未选中”)
Map resultMap=mapper.readValue(conteudo,HashMap.class);
setValues(resultMap);
return-oathToken=new-OAuthToken(resultMap.get(KEY\u-ACCESS\u-TOKEN),resultMap.get(KEY\u-TOKEN\u-TYPE));
}
}
不幸的是,它不支持经过身份验证的连接,这意味着您每天最多可以发送500次推送。它似乎被抛弃了。最后一次提交是在11个月前。@ Drkj-Sukkeli我修复了bug蚁,它现在工作得很好。看@plucury哦,谢谢!我必须纠正自己每天推500次。它是按应用程序、日期和用户计算的。所以,除非你想向一个用户推500次以上(这是很多次),否则这不是问题。而且它并没有被放弃:-)您正在寻找能够向windows Phone应用程序发送消息的Java SDK/API
public abstract class AbstractCloudMediator {
private static final Logger LOG = Logger.getLogger(AbstractCloudMediator.class.getSimpleName());
@Autowired
private HttpClientFactory clientFactory;
@Autowired
protected ObjectMapper mapper;
public abstract boolean sendMessage(Jogador destinatario, Action mensagem);
protected String postToString(HttpPost post) throws IOException, ClientProtocolException {
HttpResponse response = executeMethod(post);
return responseToString(response);
}
protected String responseToString(HttpResponse response) throws IOException {
InputStream conteudoResposta = response.getEntity().getContent();
try {
return IOUtils.toString(conteudoResposta);
} finally {
IOUtils.closeQuietly(conteudoResposta);
}
}
protected HttpResponse executeMethod(HttpPost post) throws IOException, ClientProtocolException {
LOG.info("posting to... " + post);
return clientFactory.create().execute(post);
}
}
@Service(SharedConstants.WINDOWS_CLOUD_BEAN)
public class WindowsPushNotificationMediator extends AbstractCloudMediator { // NO_UCD (test only)
private static final Logger LOG = Logger.getLogger(WindowsPushNotificationMediator.class.getName());
private static final String KEY_ACCESS_TOKEN = "access_token";
private static final String KEY_TOKEN_TYPE = "token_type";
@Resource(name = "authenticateWNSHeaders")
private Map<String, String> authenticateWNSHeaders;
@Resource(name = "authenticateWNSPostParams")
private Map<String, String> authenticateWNSPostParams;
@Resource(name = "sendMessageWNSHeaders")
private Map<String, String> sendMessageWNSHeaders;
@Autowired
@Qualifier("authenticateUrlPostWNS")
private String authenticateUrlPostWNS;
@Autowired
private CloudMessagingDAO cloudMessagingDAO;
private OAuthToken oathToken;
@Override
public boolean sendMessage(Jogador destinatario, Action mensagem) {
try {
OAuthToken token = getToken();
String jsonString = mapper.writeValueAsString(mensagem);
StringEntity entity = new StringEntity(jsonString, Consts.UTF_8);
return sendMessage(destinatario, entity, token);
} catch (IOException e) {
LOG.log(Level.SEVERE, e.getMessage(), e);
throw new RuntimeException(e);
}
}
private boolean sendMessage(Jogador destinatario, HttpEntity entity, OAuthToken token) throws IOException {
HttpPost post = new HttpPost(destinatario.getCloudMessagingInfo());// this is the client url
post.addHeader("Authorization", token.getAuthorization());
addPostHeaders(post, sendMessageWNSHeaders);
post.setEntity(entity);
HttpResponse response = executeMethod(post);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
return sendMessage(destinatario, entity, getNewToken());
}
Header[] allHeaders = response.getAllHeaders();
StringBuilder builder = new StringBuilder();
for (Header header : allHeaders) {
builder.append(header.getName() + ": " + header.getValue());
builder.append('\n');
}
LOG.info(builder.toString());
return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
}
private void addPostHeaders(HttpPost post, Map<String, String> postHeaders) {
for (String key : postHeaders.keySet()) {
post.addHeader(key, postHeaders.get(key));
}
}
private OAuthToken getToken() throws IOException {
if (oathToken == null) {
//You should store your access token, so you can reuse it until it expires
String token = cloudMessagingDAO.getValue(KEY_ACCESS_TOKEN);
String tokenType = cloudMessagingDAO.getValue(KEY_TOKEN_TYPE);
if (StringUtils.isNotBlank(token) && StringUtils.isNotBlank(tokenType)) {
return oathToken = new OAuthToken(token, tokenType);
}
return getNewToken();
}
return oathToken;
}
private OAuthToken getNewToken() throws IOException {
HttpPost post = new HttpPost(authenticateUrlPostWNS);
addPostHeaders(post, authenticateWNSHeaders);
List<NameValuePair> params = new ArrayList<>();
for (String key : authenticateWNSPostParams.keySet()) {
params.add(new BasicNameValuePair(key, authenticateWNSPostParams.get(key)));
}
post.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = executeMethod(post);
String conteudo = responseToString(response);
LOG.info(conteudo);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
throw new NegocioException("Falha ao autenticar no serviço: " + conteudo);
}
@SuppressWarnings("unchecked")
Map<String, String> resultMap = mapper.readValue(conteudo, HashMap.class);
cloudMessagingDAO.setValues(resultMap);
return oathToken = new OAuthToken(resultMap.get(KEY_ACCESS_TOKEN), resultMap.get(KEY_TOKEN_TYPE));
}
}