Android中使用socket通信实现消息推送的方法详解

原理
最近用socket写了一个消息推送的demo,在这里和大家分享一下。

主要实现了:一台手机向另外一台手机发送消息,这两台手机可以随时自由发送文本消息进行通信,类似我们常用的QQ。

效果图:

原理:手机通过socket发送消息到服务器,服务器每接收到一条消息之后,都会把这条消息放进一个messageList里面,服务器会不停地检测messageList是否含有消息,如果有的话就会根据messageList里面item的数据,推送到相应的另一端手机上面。

下面简单画了一个图来说明这个原理:

演示:手机客户端client1发送消息msg1到手机客户端client2,client2收到消息后回复msg2给client1

1.手机客户端client1发送一条“msg1”的文本消息到服务器;

2.服务器收到来自client1的“msg1”消息后,把它add进messageList里面;

3.服务器检测到messageList里面含有消息(开启服务器时就新建里一个检测messageList的线程,线程里面有一个死循环,用于不停检测messageList是否含有消息);

4.服务器读取消息数据,如读取到来自client1发给client2的消息“msg1”,那么服务器就把“msg1”推送到client2上;

5.client2检测到服务器推送的消息,做出相应的操作(如:震动、铃声、显示消息等);

6.client2接收到来自服务器推送的“msg1”消息后,client2也回复一条文本消息“msg2”给client1,此过程和client1发送消息给client2一样。

7.最后,client2就可以显示来自client1发送的消息“msg1”,而client1则可以显示来自client2的回复消息“msg2”。

实现过程
根据消息推送的原理图,我们的实现过程主要分为Server端和Client端,Server端采用Java的编程,而Client端则用Android编程。

所以在这里也分别创建了两个工程SocketServer和SocketClient

我们先来看一下SocketMessage.java类:

public class SocketMessage { 

  public int to;//socketID,指发送给谁
  public int from;//socketID,指谁发送过来的
  public String msg;//消息内容
  public String time;//接收时间
  public SocketThread thread;//socketThread下面有介绍
}

该类是一个消息类,用于表示消息是由谁发给谁的、消息内容是什么、接收时间是多少,只有几个属性,比较简单。

而MyServer.java类就相对比较多一些代码:

package com.jimstin.server; 

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date; 

import org.json.JSONObject; 

import com.jimstin.msg.SocketMessage; 

public class MyServer { 

  private boolean isStartServer;
  private ServerSocket mServer;
  /**
   * 消息队列,用于保存SocketServer接收来自于客户机(手机端)的消息
   */
  private ArrayList<SocketMessage> mMsgList = new ArrayList<SocketMessage>();
  /**
   * 线程队列,用于接收消息。每个客户机拥有一个线程,每个线程只接收发送给自己的消息
   */
  private ArrayList<SocketThread> mThreadList = new ArrayList<SocketThread>(); 

  /**
   * 开启SocketServer
   */
  private void startSocket() {
    try {
      isStartServer = true;
      int prot = 2000;//端口可以自己设置,但要和Client端的端口保持一致
      mServer = new ServerSocket(prot);//创建一个ServerSocket
      System.out.println("启动server,端口:"+prot);
      Socket socket = null;
      int socketID = 0;//Android(SocketClient)客户机的唯一标志,每个socketID表示一个Android客户机
      //开启发送消息线程
      startSendMessageThread();
      //用一个循环来检测是否有新的客户机加入
      while(isStartServer) {
        //accept()方法是一个阻塞的方法,调用该方法后,
        //该线程会一直阻塞,直到有新的客户机加入,代码才会继续往下走
        socket = mServer.accept();
        //有新的客户机加入后,则创建一个新的SocketThread线程对象
        SocketThread thread = new SocketThread(socket, socketID++);
        thread.start();
        //将该线程添加到线程队列
        mThreadList.add(thread);
      } 

    } catch (Exception e) {
      e.printStackTrace();
    }
  } 

  /**
   * 开启推送消息线程,如果mMsgList中有SocketMessage,则把该消息推送到Android客户机
   */
  public void startSendMessageThread() {
    new Thread(){
      @Override
      public void run() {
        super.run();
        try {
          /*如果isStartServer=true,则说明SocketServer已启动,
          用一个循环来检测消息队列中是否有消息,如果有,则推送消息到相应的客户机*/
          while(isStartServer) {
            //判断消息队列中的长度是否大于0,大于0则说明消息队列不为空
            if(mMsgList.size() > 0) {
              //读取消息队列中的第一个消息
              SocketMessage from = mMsgList.get(0);
              for(SocketThread to : mThreadList) {
                if(to.socketID == from.to) {
                  BufferedWriter writer = to.writer;
                  JSONObject json = new JSONObject();
                  json.put("from", from.from);
                  json.put("msg", from.msg);
                  json.put("time", from.time);
                  //writer写进json中的字符串数据,末尾记得加换行符:"\n",否则在客户机端无法识别
                  //因为BufferedReader.readLine()方法是根据换行符来读取一行的
                  writer.write(json.toString()+"\n");
                  //调用flush()方法,刷新流缓冲,把消息推送到手机端
                  writer.flush();
                  System.out.println("推送消息成功:"+from.msg+">> to socketID:"+from.to);
                  break;
                }
              }
              //每推送一条消息之后,就要在消息队列中移除该消息
              mMsgList.remove(0);
            }
            Thread.sleep(200);
          }
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }.start();
  } 

  /**
   * 定义一个SocketThread类,用于接收消息
   *
   */
  public class SocketThread extends Thread { 

    public int socketID;
    public Socket socket;//Socket用于获取输入流、输出流
    public BufferedWriter writer;//BufferedWriter 用于推送消息
    public BufferedReader reader;//BufferedReader 用于接收消息 

    public SocketThread(Socket socket, int count) {
      socketID = count;
      this.socket = socket;
      System.out.println("新增一台客户机,socketID:"+socketID);
    } 

    @Override
    public void run() {
      super.run(); 

      try {
        //初始化BufferedReader
        reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
        //初始化BufferedWriter
        writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "utf-8"));
        //如果isStartServer=true,则说明SocketServer已经启动,
        //现在需要用一个循环来不断接收来自客户机的消息,并作其他处理
        while(isStartServer) {
          //先判断reader是否已经准备好
          if(reader.ready()) {
            /*读取一行字符串,读取的内容来自于客户机
            reader.readLine()方法是一个阻塞方法,
            从调用这个方法开始,该线程会一直处于阻塞状态,
            直到接收到新的消息,代码才会往下走*/
            String data = reader.readLine();
            //讲data作为json对象的内容,创建一个json对象
            JSONObject json = new JSONObject(data);
            //创建一个SocketMessage对象,用于接收json中的数据
            SocketMessage msg = new SocketMessage();
            msg.to = json.getInt("to");
            msg.msg = json.getString("msg");
            msg.from = socketID;
            msg.time = getTime(System.currentTimeMillis());
            //接收到一条消息后,将该消息添加到消息队列mMsgList
            mMsgList.add(msg);
            System.out.println("收到一条消息:"+json.getString("msg")+" >>>> to socketID:"+json.getInt("to"));
          }
          //睡眠100ms,每100ms检测一次是否有接收到消息
          Thread.sleep(100);
        } 

      } catch (Exception e) {
        e.printStackTrace();
      }  

    }
  }
  /**
   * 获取指定格式的时间字符串,通过毫秒转换日期
   * @param millTime
   */
  private String getTime(long millTime) {
    Date d = new Date(millTime);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    return sdf.format(d);
  }
  public static void main(String[] args) {
    MyServer server = new MyServer();
    server.startSocket();
  } 

}

2.SocketClient工程

该工程是一个Android的工程,只有一个MainActivity.java和activity_main.xml文件,

先看一下activity_main.xml布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity"
  android:orientation="vertical" > 

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <EditText
      android:id="@+id/ip_edt"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:hint="ip"
      android:text="172.16.1.200"/>
    <EditText
      android:id="@+id/port_edt"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_weight="1"
      android:hint="port"
      android:text="2000"/>
  </LinearLayout>
  <Button
    android:id="@+id/start_btn"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="start"/>
  <EditText
    android:id="@+id/socket_id_edt"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="socketID"/> 

  <EditText
    android:id="@+id/msg_edt"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minLines="5"
    android:hint="content"
    android:gravity="top"
    />
  <Button
    android:id="@+id/send_btn"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="send"/>
  <TextView
    android:id="@+id/console_txt"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"/>
  <Button
    android:id="@+id/clear_btn"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="clear"/>
</LinearLayout>

效果图:

MainActivity.java类:

package com.jimstin.socketclient; 

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date; 

import org.json.JSONObject; 

import com.tencent.stat.MtaSDkException;
import com.tencent.stat.StatConfig;
import com.tencent.stat.StatService; 

import android.R.integer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.app.Activity; 

public class MainActivity extends Activity implements OnClickListener { 

  private EditText mIPEdt, mPortEdt, mSocketIDEdt, mMessageEdt;
  private static TextView mConsoleTxt; 

  private static StringBuffer mConsoleStr = new StringBuffer();
  private Socket mSocket;
  private boolean isStartRecieveMsg; 

  private SocketHandler mHandler;
  protected BufferedReader mReader;//BufferedWriter 用于推送消息
  protected BufferedWriter mWriter;//BufferedReader 用于接收消息 

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();
  } 

  private void initView() {
    mIPEdt = (EditText) findViewById(R.id.ip_edt);
    mPortEdt = (EditText) findViewById(R.id.port_edt);
    mSocketIDEdt = (EditText) findViewById(R.id.socket_id_edt);
    mMessageEdt = (EditText) findViewById(R.id.msg_edt);
    mConsoleTxt = (TextView) findViewById(R.id.console_txt);
    findViewById(R.id.start_btn).setOnClickListener(this);
    findViewById(R.id.send_btn).setOnClickListener(this);
    findViewById(R.id.clear_btn).setOnClickListener(this);
    mHandler = new SocketHandler();
  } 

  /**
   * 初始化socket
   */
  private void initSocket() {
    //新建一个线程,用于初始化socket和检测是否有接收到新的消息
    Thread thread = new Thread(new Runnable() { 

      @Override
      public void run() {
        String ip = mIPEdt.getText().toString();//IP
        int port = Integer.parseInt(mPortEdt.getText().toString());//Socket 

        try {
          isStartRecieveMsg = true;
          mSocket = new Socket(ip, port);
          mReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream(), "utf-8"));
          mWriter = new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream(), "utf-8"));
          while(isStartRecieveMsg) {
            if(mReader.ready()) {
              /*读取一行字符串,读取的内容来自于客户机
              reader.readLine()方法是一个阻塞方法,
              从调用这个方法开始,该线程会一直处于阻塞状态,
              直到接收到新的消息,代码才会往下走*/
              String data = mReader.readLine();
              //handler发送消息,在handleMessage()方法中接收
              mHandler.obtainMessage(0, data).sendToTarget();
            }
            Thread.sleep(200);
          }
          mWriter.close();
          mReader.close();
          mSocket.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
    thread.start();
  } 

  @Override
  public void onClick(View v) {
    switch (v.getId()) {
    case R.id.send_btn:
      send();
      break;
    case R.id.clear_btn:
      mConsoleStr.delete(0, mConsoleStr.length());
      mConsoleTxt.setText(mConsoleStr.toString());
      break;
    case R.id.start_btn:
      if(!isStartRecieveMsg) {
        initSocket();
      }
      break;
    default:
      break;
    }
  } 

  /**
   * 发送
   */
  private void send() {
    new AsyncTask<String, Integer, String>() { 

      @Override
      protected String doInBackground(String... params) {
        sendMsg();
        return null;
      }
    }.execute();
  }
  /**
   * 发送消息
   */
  protected void sendMsg() {
    try {
      String socketID = mSocketIDEdt.getText().toString().trim();
      String msg = mMessageEdt.getText().toString().trim();
      JSONObject json = new JSONObject();
      json.put("to", socketID);
      json.put("msg", msg);
      mWriter.write(json.toString()+"\n");
      mWriter.flush();
      mConsoleStr.append("我:" +msg+"  "+getTime(System.currentTimeMillis())+"\n");
      mConsoleTxt.setText(mConsoleStr);
    } catch (Exception e) {
      e.printStackTrace();
    }
  } 

  static class SocketHandler extends Handler { 

    @Override
    public void handleMessage(Message msg) {
      // TODO Auto-generated method stub
      super.handleMessage(msg);
      switch (msg.what) {
      case 0:
        try {
          //将handler中发送过来的消息创建json对象
          JSONObject json = new JSONObject((String)msg.obj);
          mConsoleStr.append(json.getString("from")+":" +json.getString("msg")+"  "+getTime(System.currentTimeMillis())+"\n");
          //将json数据显示在TextView中
          mConsoleTxt.setText(mConsoleStr);
        } catch (Exception e) {
          e.printStackTrace();
        } 

        break; 

      default:
        break;
      }
    }
  } 

  @Override
  public void onBackPressed() {
    super.onBackPressed();
    isStartRecieveMsg = false;
  } 

  private static String getTime(long millTime) {
    Date d = new Date(millTime);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    return sdf.format(d);
  } 

}

以上代码的注释都比较详细,就不再多说了。

(0)

相关推荐

  • 详解Android使用Socket对大文件进行加密传输

    前言 数据加密,是一门历史悠久的技术,指通过加密算法和加密密钥将明文转变为密文,而解密则是通过解密算法和解密密钥将密文恢复为明文.它的核心是密码学. 数据加密目前仍是计算机系统对信息进行保护的一种最可靠的办法.它利用密码技术对信息进行加密,实现信息隐蔽从而起到保护信息的安全的作用. 项目中使用Socket进行文件传输过程时,需要先进行加密.实现的过程中踏了一些坑,下面对实现过程进行一下总结. DES加密 由于加密过程中使用的是DES加密算法,下面贴一下DES加密代码: //秘钥算法 privat

  • python服务器与android客户端socket通信实例

    本文实例讲述了python服务器与android客户端socket通信的方法.分享给大家供大家参考.具体实现方法如下: 首先,服务器端使用python完成,下面为python代码: 复制代码 代码如下: #server.py  import socket  def getipaddrs(hostname):#只是为了显示IP,仅仅测试一下      result = socket.getaddrinfo(hostname, None, 0, socket.SOCK_STREAM)      re

  • android Socket实现简单聊天功能以及文件传输

    干程序是一件枯燥重复的事,每当感到内心浮躁的时候,我就会找小说来看.我从小就喜爱看武侠小说,一直有着武侠梦.从金庸,古龙,梁羽生系列到凤歌(昆仑),孙晓(英雄志)以及萧鼎的(诛仙)让我领略着不一样的江湖. 如果你有好看的武侠系列小说,给我留言哦.题外话就扯这么多了,接着还是上技术. 看看今天实现的功能效果图: 可以这里使用多台手机进行通讯,我采用的服务器发送消息. 是不是只有发送消息,有些显得太单调了.好,在发送消息的基础上增加文件传输.后期会增加视频,音频的传输,增加表情包.那一起来看看图文消

  • Android开发之Socket通信传输简单示例

    本文实例讲述了Android Socket通信传输实现方法.分享给大家供大家参考,具体如下: 1.开篇简介 Socket本质上就是Java封装了传输层上的TCP协议(注:UDP用的是DatagramSocket类).要实现Socket的传输,需要构建客户端和服务器端.另外,传输的数据可以是字符串和字节.字符串传输主要用于简单的应用,比较复杂的应用(比如Java和C++进行通信),往往需要构建自己的应用层规则(类似于应用层协议),并用字节来传输. 2.基于字符串传输的Socket案例 1)服务器端

  • Android编程之客户端通过socket与服务器通信的方法

    本文实例讲述了Android编程之客户端通过socket与服务器通信的方法.分享给大家供大家参考,具体如下: 下面是一个demo,Android客户端通过socket与服务器通信. 由于Android里面可以完全使用java.io.*包和java.net.*包,那么,实际上,逻辑部分与J2SE没有区别.只是UI代码不一样. Android客户端通过socket与服务器通信分为下面5步: (1)通过IP地址和端口实例化Socket,请求连接服务器: 复制代码 代码如下: socket = new

  • Android中Socket通信的实现方法概述

    本文实例简述了Android中Socket通信的实现方法,具体内容如下: 一.socket通信概述 通俗的来说套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元.它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口. 应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题.多个TCP连接或多个应用程序进程可能需要通过同一个TCP

  • Android开发中Socket通信的基本实现方法讲解

    一.Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是"请求-响应方式",即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据.而Socket通信则是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求. 那么,什么是socket?Socket又称套接字,在程序内部提供了与外界通信的端口,即端口通信.通过建

  • android开发socket编程之udp发送实例分析

    本文实例讲述了android开发socket编程之udp发送实现方法.分享给大家供大家参考.具体分析如下: 需要实现的功能:采用udp下的socket编程,当按下确认键,模拟器发送文本框数据,pc机上的网络调试助手接收 一.环境: win7 + eclipse + sdk 二.代码: package test.soket; //import com.test_button.R; import java.io.DataOutputStream; import java.io.IOException

  • Android Socket通信详解

    一.Socket通信简介  Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是"请求-响应方式",即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据.而Socket通信则是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求. 那么,什么是socket?Socket又称套接字,在程序内部提供了与外界通信的端口,即端口通信.通过

  • Android中使用socket通信实现消息推送的方法详解

    原理 最近用socket写了一个消息推送的demo,在这里和大家分享一下. 主要实现了:一台手机向另外一台手机发送消息,这两台手机可以随时自由发送文本消息进行通信,类似我们常用的QQ. 效果图: 原理:手机通过socket发送消息到服务器,服务器每接收到一条消息之后,都会把这条消息放进一个messageList里面,服务器会不停地检测messageList是否含有消息,如果有的话就会根据messageList里面item的数据,推送到相应的另一端手机上面. 下面简单画了一个图来说明这个原理: 演

  • Android中一种效果奇好的混音方法详解

    初识音频 从初中物理上我们就学到,声音是一种波.计算机只能处理离散的信号,通过收集足够多的离散的信号,来不断逼近波形,这个过程我们叫做采样.怎么样才能更好的还原声音信息呢?这里很自然引出两个概念了. 采样频率(Sample Rate):每秒采集声音的数量,它用赫兹(Hz)来表示. 采样率越高越靠近原声音的波形,常见的采样率有以下几种: 8khz:电话等使用,对于记录人声已经足够使用. 22.05khz:广播使用频率. 44.1kb:音频CD. 48khz:DVD.数字电视中使用. 96khz-1

  • Java Web项目中使用Socket通信多线程、长连接的方法

    很多时候在javaweb项目中我们需要用到Socket通信来实现功能,在web中使用Socket我们需要建立一个监听程序,在程序启动时,启动socket监听.我们的应用场景是在java项目中,需要外接如一个硬件设备,通过tcp通信,获取设备传上来的数据,并对数据做回应. 先看一下web的监听代码: import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class

  • vue-vuex中使用commit提交mutation来修改state的方法详解

    在vuex中,关于修改state的方式,需要commit提交mutation.官方文档中有这么一句话: 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation. 为了搞清楚其原因,查阅了很多资料,发现其它人在做vuex的源码解析的时候,并没有将这点说的很明白. 所以只好自己去查看vuex的源码,并且自己做demo进行验证. 但是试验后,发现直接修改state时,store中的state能够改变,并且是响应式的,并没有报错.跟commit提交mutation的方式没啥区别. 后

  • 对DataFrame数据中的重复行,利用groupby累加合并的方法详解

    pandas读取一组数据,可能存在重复索引,虽然可以利用drop_duplicate直接删除,但是会删除重要信息. 比如同一ID用户,多次登录学习时间.要计算该用户总共''学习时间'',就要把重复的ID的''学习时间''累加. 可以结合groupby和sum函数完成该操作. 实例如下: 新建一个DataFrame,计算每个 id 的总共学习时间.其中 id 为one/two的存在重复学习时间.先利用 groupby 按照键 id 分组,然后利用sum()函数求和,即可得到每个id的总共学习时间.

  • 对Python中实现两个数的值交换的集中方法详解

    如下所示: #定义两个数并赋值 x = 1 y = 2 #第1种方式:引入第三方变量 z = 0 z = x x = y y = z #第2种:不引入第三方变量 x = x+y y = x-y x = x-y #第3种:推荐 x,y = y,x print("x=%d,y=%d"%(x,y)) 以上这篇对Python中实现两个数的值交换的集中方法详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • 关于Python 中的时间处理包datetime和arrow的方法详解

    在获取贝壳分的时候用到了时间处理函数,想要获取上个月时间包括年.月.日等 # 方法一: today = datetime.date.today() # 1. 获取「今天」 first = today.replace(day=1) # 2. 获取当前月的第一天 last_month = first - datetime.timedelta(days=1) # 3. 减一天,得到上个月的最后一天 print(last_month.strftime("%Y%m")) # 4. 格式化成指定形

  • Javaweb中Request获取表单数据的四种方法详解

    目录 表单代码 request.getParamter(String name);通过name获取值 request.getParamterValues(String name);通过name获取value值(一般用于复选框获取值) 代码片段 request.getParameterNames();直接获取表单所有对象的name值,返回值是枚举集合 request.getParameterMap();直接获取表单所有对象的name值以及数据 表单代码 <!DOCTYPE html> <h

  • react-native使用leanclound消息推送的方法

    iOS消息推送的基本流程 1.注册:为应用程序申请消息推送服务.此时你的设备会向APNs服务器发送注册请求.2. APNs服务器接受请求,并将deviceToken返给你设备上的应用程序 3.客户端应用程序将deviceToken发送给后台服务器程序,后台接收并储存. 4.后台服务器向APNs服务器发送推送消息 5.APNs服务器将消息发给deviceToken对应设备上的应用程序 使用leanclound进行消息推送 优势:文档清晰,价格便宜 接入Leanclound 1.首先需要创建一个re

  • php基于Redis消息队列实现的消息推送的方法

    基本知识点 重点用到了以下命令实现我们的消息推送 brpop 阻塞模式 从队列右边获取值之后删除 brpoplpush 从队列A的右边取值之后删除,从左侧放置到队列B中 逻辑分析 在普通的任务脚本中写入push_queue队列要发送消息的目标,并为目标设置一个要推送的内容,永不过期 RedisPushQueue中brpoplpush处理,处理后的值放到temp_queue,主要防止程序崩溃造成推送失败 RedisAutoDeleteTempqueueItems处理temp_queue,这里用到了

随机推荐