[Java]直播方案----[接入环信聊天室]+[腾讯云直播]
辛辛苦苦写的,转载请注明一下,这点信任我想还是有的吧,谢谢了。
http://www.cnblogs.com/applerosa/p/7162268.html
之前做了直播,一直没时间写,好不容易闲下来,所以总结记录一下.
需要注意的是,在获取环信聊天室ID和腾讯云三个推/拉流地址的时候,需要先去注册,获取所用开发者账号。
所以这个教程所必须的东西:
1.环信开发者账号;
2.腾讯云开发者账号;
一、做直播,肯定要有一个直播模型,这里我们用直播间来做示例:
这里只是做个基础的演示,所以都是必须的字段,实际业务需求不一样,酌情添加.
CREATE TABLE `live_room` (
`id` INT(32) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '精品直播主键',
`room_title` VARCHAR(256) NOT NULL COMMENT '直播间标题',
`room_desc` VARCHAR(256) NULL DEFAULT NULL COMMENT '直播间描述/简介',
`chatroom_id` VARCHAR(16) NULL DEFAULT NULL COMMENT '聊天室ID',
`push_url` VARCHAR(256) NULL DEFAULT NULL COMMENT '推流地址',
`pull_url` VARCHAR(256) NULL DEFAULT NULL COMMENT 'HTTP拉流地址',
`pull_rtmp_url` VARCHAR(256) NULL DEFAULT NULL COMMENT 'RTMP拉流地址',
`video_url` VARCHAR(255) NULL DEFAULT NULL COMMENT '录播视频url',
`status` TINYINT(2) UNSIGNED NOT NULL DEFAULT '' COMMENT '直播状态:0-初始化 1-直播中 2-已结束',
`create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
建表语句
大概就这样的:
表结构贴出来了,其余的实体,操作语句什么的就不贴了,代码生成器就帮你搞定了.
这里主要想说一下腾讯的三个推/拉流地址:
1.推流地址 push_url 就是你需要推送给腾讯的数据流地址,理论上可以是视频,也可以是音频;
2.HTTP拉流地址 pull_url 也就是APP拉流地址;
3.RTMP拉流地址 pull_rtmp_url 也就是我们说的PC拉流地址.
另外补充一下录播视频 video_url 就是,如果我们开通腾讯直播的时候,使用了录播功能,在直播结束后,我们可以查询到腾讯录制的视频文件地址,然后用来播放.
二、腾讯云地址的获取
先贴个腾讯云直播的API地址:https://www.qcloud.com/document/product/267/7976?!preview=true&lang=zh
大家可以点进去看看详情.这里就简单说一下,可以看到,他提供了两种直播方式:
第一种是直播码接入方式,这种模式呢,地址生成方便,地址由我们后台生成,要用的时候直接用就可以,可靠性也高,所以这个例子中就是直播码模式.
然后当第一次使用这个地址的时候,腾讯云会检测这个地址中包含的信息,看是否符合规则,符合规则就开始推流,开始直播.
第二种频道模式,就是每次创建地址都要去腾讯请求,然后他生成可用的地址返回给你,然后你再存入库,用的时候再拿出来用.
这是他官网上的比较:
其他的大家可以仔细看看官网,下面开整!
1. 拼接腾讯三个推拉流地址,下面是工具类,大家可以直接拿去用.
关于详细的生成规则,腾讯API有详细说明:https://www.qcloud.com/document/product/267/7977?!preview=true&lang=zh
关于开发者信息的地址:https://console.qcloud.com/live/livecodemanage
因为这里我的工具类中有相关账号信息,所以大家到时候需要做相应替换.
上面的信息大家根据对应的替换就可以
根据API中的介绍
下面是我们就是我们需要的结果了:
好了,下面贴工具类,记得按上面的规则替换信息.
import org.apache.log4j.Logger; /**
* 腾讯推流、拉流工具
*
* @author lnexin@aliyun.com
*/
public class TecentCloudUtils { @SuppressWarnings("unused")
// 这就是个日志,不需要的删掉就行了
private static final Logger logger = Logger.getLogger(TecentCloudUtils.class); // 用于 生成推流防盗链的key
public static final String key = "替换自己的开发者信息,谢谢!"; public static final String bizid = "替换自己的开发者信息,谢谢!"; public static final String APPID = "替换自己的开发者信息,谢谢!"; // 用于主动查询和被动通知的key:API鉴定key
public static final String API_KEY = "替换自己的开发者信息,谢谢!"; // API回调地址
public static final String API_ADDRESS = "http://fcgi.video.qcloud.com/common_access"; /**
* 推流地址
*/
public static final String PUSH_URL = "rtmp://" + bizid + ".livepush.myqcloud.com/live/" + bizid + "_"; /**
* PC拉流地址
*/
public static final String PULL_RTMP_URL = "rtmp://" + bizid + ".liveplay.myqcloud.com/live/"+ bizid + "_";
/**
* app拉流地址
*/
public static final String PULL_URL = "http://" + bizid + ".liveplay.myqcloud.com/live/"+ bizid + "_"; /**
* 这是推流防盗链的生成 KEY+ streamId + txTime
*
* @param key
* 防盗链使用的key
* @param streamId
* 通常为直播码.示例:bizid+房间id
* @param txTime
* 到期时间
* @return
* @author lnexin@aliyun.com
*/
public static String getSafeUrl(String key, String streamId, long txTime) {
String input = new StringBuilder().append(key).append(streamId).append(Long.toHexString(txTime).toUpperCase()).toString(); String txSecret = null; txSecret = MD5Encode.stringToMD5(input); return txSecret == null ? "" : new StringBuilder().append("txSecret=").append(txSecret).append("&").append("txTime=").append(Long.toHexString(txTime).toUpperCase()).toString();
} /**
* 推流地址生成
*/
public static String getPushUrl(String roomId) {
Long now = System.currentTimeMillis() + 60L * 60L * 24L * 30L * 1000L;// 要转成long类型,不然为负数
// 当前毫秒数+需要加上的时间毫秒数 = 过期时间毫秒数
Long txTime = now / 1000;// 推流码过期时间秒数 String safeUrl = getSafeUrl(key, bizid + "_" + roomId, txTime); String realPushUrl = PUSH_URL + roomId + "?bizid=" + bizid + "&" + safeUrl; return realPushUrl;
} /**
* APP拉流地址获得
*/
public static String getPullUrl(String owenrId) {
String appPullUrl = PULL_URL + owenrId + ".flv";
return appPullUrl;
} /**
* PC拉流地址获得
*/
public static String getPullRtmpUrl(String owenrId) {
String pullRtmpUrl = PULL_RTMP_URL + owenrId;
return pullRtmpUrl;
} /**
* 获取关闭直播的url关闭直播 需要发送请求给腾讯服务器,然后返回结果
*
* @param id
* 需要关闭的房间ID
* @return 关闭直播的url
* @author lnexin@aliyun.com
* @date 2017年7月22日 下午2:54:14
*/
public static String getCloseLiveUrl(String id) {
// 此请求的有效时间
Long current = System.currentTimeMillis() / 1000 + 10;
// 生成sign签名
String sign = MD5Encode.stringToMD5(new StringBuffer().append(API_KEY).append(current).toString());
// 生成需要关闭的直播码
String code = bizid + "_" + id;
// 生成关闭的参数列表
String params = new StringBuffer().append("&interface=Live_Channel_SetStatus").append("&Param.s.channel_id=").append(code).append("&Param.n.status=0").append("&t=").append(current).append("&sign=").append(sign).toString(); // 拼接关闭URL
String url = API_ADDRESS + "?appid=" + APPID + params;
return url;
} /**
* 获取录播查询请求地址
*
* @param id
* @return
* @author lnexin@aliyun.com
* @date 2017年7月22日 下午12:45:57
*/
public static String getRecordUrl(String id) {
Long current = (System.currentTimeMillis() + 60 * 60 * 24 * 1000) / 1000;
String sign = MD5Encode.stringToMD5(new StringBuffer().append(API_KEY).append(current).toString());
String code = bizid + "_" + id;
String params = new StringBuffer().append("&interface=Live_Tape_GetFilelist").append("&Param.s.channel_id=").append(code).append("&t=").append(current).append("&sign=").append(sign).toString(); // 拼接URL
String url = API_ADDRESS + "?appid=" + APPID + params;
return url;
} }
当你替换为你自己对应的信息之后,就可以使用这个工具类生成三个地址,和关闭地址,查询录播视频地址了.如:
// 腾讯云获取推流地址、拉流地址
String pushUrl = TecentCloudUtils.getPushUrl(roomId);
String pullUrl = TecentCloudUtils.getPullUrl(roomId);
String pullRtmpUrl = TecentCloudUtils.getPullRtmpUrl(roomId);
这里传入的参数(roomId)只要是你这个直播间唯一标识就行,类型不重要的,是不是主键也不重要,你也可以改成其他类型,目的只是为了生成的地址不重复就好;
获取的地址存入库,要直播的时候拿出来用就可以了.
这里强调一下:
这个地址按规则生成以后,腾讯云并无这个房间,只是在第一次使用的时候,我们向这个地址推流,然后腾讯云接受到这个地址,检测地址中的信息,看是否符合规则,符合规则就在云上创建直播间,然后开始推/拉流;
等于说我们创建地址的时候,根本不需要和腾讯云通讯.
这里补充一个上面工具中使用到的MD5工具,当然大家也可以用自己的。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest; public class MD5Encode { public static String stringToMD5(String str) { try {
byte[] strTemp = str.getBytes();
MessageDigest mdTemp = MessageDigest.getInstance("MD5");
mdTemp.update(strTemp);
return toHexString(mdTemp.digest());
} catch (Exception e) {
return null;
}
} public static String fileNameToMD5(String fileName) {
InputStream inputStream = null;
try {
inputStream = new FileInputStream(fileName);
return streamToMD5(inputStream);
} catch (Exception e) {
return null;
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} public static String streamToMD5(InputStream inputStream) {
try {
MessageDigest mdTemp = MessageDigest.getInstance("MD5");
byte[] buffer = new byte[1024];
int numRead = 0;
while ((numRead = inputStream.read(buffer)) > 0) {
mdTemp.update(buffer, 0, numRead);
}
return toHexString(mdTemp.digest());
} catch (Exception e) {
return null;
}
} private static String toHexString(byte[] md) {
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f' };
int j = md.length;
char str[] = new char[j * 2];
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[2 * i] = hexDigits[byte0 >>> 4 & 0xf];
str[i * 2 + 1] = hexDigits[byte0 & 0xf];
}
return new String(str);
}
}
MD5Encode
三、环信聊天室
既然是直播,我们就需要清楚,我们需要的是“聊天室”模式,就是从开始直播创建一个聊天室之后,每进入一个用户,就加入这个聊天室,然后在聊天室中聊天,就是我们常说的互动。
环信手册:http://docs.easemob.com/im/100serverintegration/10intro
服务端集成:http://docs.easemob.com/im/live/server-integration
因为我这里只需要一个聊天室ID所以就做了其余的辅助:如创建时验证用户权限,从返回信息中筛选出我需要的信息,多余的功能大家可以根据需求来删减;
这里有额外依赖:
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
关于log的依赖,大家也可以删除:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency> <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
Log4j的依赖
下面是主要工具类文件:(只复制这个一定会报错)
import java.util.ArrayList;
import java.util.List; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import net.sf.json.JSONObject; /**
* 创建环信聊天室
* @author lnexin@aliyun.com
*/
public class CreateChatRoom { private static final Logger logger = LoggerFactory.getLogger(CreateChatRoom.class);
/**
*
* @param roomsName
* @param desc
* @param owner
* @param userIds
* @return
*
* 注:服务器需求格式为
* {"name":"testchatroom","description":"server create chatroom","maxusers":300,"owner":"jma1","members":["jma2","jma3"]}
*/
public static String createChatRooms(String roomsName, String desc, String owner, List<String> userIds) { try {
JSONObject params = new JSONObject();
params.put("name", roomsName);
params.put("description", desc);
params.put("maxusers", 5000); // 聊天室成员最大数(包括群主),值为数值类型,默认值200,此属性为可选的
params.put("owner", owner); if (userIds.size() > 0) {
params.put("members", userIds);
} JSONObject result = HttpTool.doPostsWithToken(HuanxinConstant.CHATROOM_URL, params.toString(), GetAdminToken.getToken()); if(result.has("error_description")) {
logger.error("错误信息:" + result.getString("error_description"));
} JSONObject object = result.getJSONObject("data"); //返回创建好的一个聊天室ID
if (!(object.get("id") == null)) {
return object.getString("id");
}
} catch (Exception e) {
return null;
} return null;
} public static void main(String[] args) {
List<String> userIds = new ArrayList<String>();
String chatRoom = createChatRooms("600000的聊天室", "大家快来聊天", "600000", userIds);
System.err.println(chatRoom);
}
}
下面是其他的一些辅助:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.protocol.Protocol; import net.sf.json.JSONObject; /**
* 获取管理员token
* @author lnexin@aliyun.com
*
*/
public class GetAdminToken { private static String url = HuanxinConstant.TOKEN_APP_URL;
private static String grant_type = HuanxinConstant.GRANT_TYPE;
private static String client_id = HuanxinConstant.CLIENT_ID;
private static String client_secret = HuanxinConstant.CLIENT_SECRET; public static String getToken() throws Exception{ JSONObject params = new JSONObject();
params.put("grant_type", grant_type);
params.put("client_id", client_id);
params.put("client_secret", client_secret); String doPosts = doPosts(url, params.toString()); JSONObject fromObject = JSONObject.fromObject(doPosts);
return (String) fromObject.get("access_token");
} @SuppressWarnings("deprecation")
public static String doPosts(String url, String params) throws UnsupportedEncodingException {
Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
Protocol.registerProtocol("https", myhttps); HttpClient client = new HttpClient();
PostMethod post = new PostMethod(url);
post.setRequestHeader("Content-Type", "application/json"); if (params != null) {
InputStream in = new ByteArrayInputStream(params.getBytes("utf-8"));
post.setRequestBody(in);
} try {
client.executeMethod(post);
return is2Str(post.getResponseBodyAsStream());
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
post.releaseConnection();
}
return null;
} public static String is2Str(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i = -1;
while ((i = is.read()) != -1) {
baos.write(i);
}
return baos.toString();
}
}
GetAdminToken
/**
* 注册环信
* @author lnexin@aliyun.com
*
*/
public class HuanXinRegist { /**
* 注册环信新用户
* @param username 需要注册的用户名
* @param password 需要注册的密码
* @param nickName 需要注册的昵称
* @return
*/
public static boolean registerUser(String username, String password, String nickName) { try {
JSONObject params = new JSONObject();
params.put("username", username);
params.put("password", password);
params.put("nickname", nickName); int status = HttpTool.doPosts(HuanxinConstant.USERS_URL, params.toString(), GetAdminToken.getToken());
if (status == 200) {
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
}
}
}
HuanXinRegist
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; public class MySSLSocketFactory implements ProtocolSocketFactory {
private SSLContext sslcontext = null; private SSLContext createSSLContext() {
SSLContext sslcontext = null;
try {
sslcontext = SSLContext.getInstance("SSL");
sslcontext.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return sslcontext;
} private SSLContext getSSLContext() {
if (this.sslcontext == null) {
this.sslcontext = createSSLContext();
}
return this.sslcontext;
} public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
} public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(host, port);
} public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
} public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException,
UnknownHostException, ConnectTimeoutException {
if (params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}
int timeout = params.getConnectionTimeout();
SocketFactory socketfactory = getSSLContext().getSocketFactory();
if (timeout == 0) {
return socketfactory.createSocket(host, port, localAddress, localPort);
} else {
Socket socket = socketfactory.createSocket();
SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
SocketAddress remoteaddr = new InetSocketAddress(host, port);
socket.bind(localaddr);
socket.connect(remoteaddr, timeout);
return socket;
}
} private static class TrustAnyTrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
} public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
} public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
}
}
MySSLSocketFactory
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.protocol.Protocol; import net.sf.json.JSONObject; /**
* HTTP请求工具
* @author lnexin@aliyun.com
*
*/
public class HttpTool {
public static String is2Str(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i = -1;
while ((i = is.read()) != -1) {
baos.write(i);
}
return baos.toString();
} public static String doPosts(String url, NameValuePair[] nameValuePairs) {
Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
Protocol.registerProtocol("https", myhttps); HttpClient client = new HttpClient();
PostMethod post = new PostMethod(url);
if (nameValuePairs != null) {
post.setRequestBody(nameValuePairs);
} try {
client.executeMethod(post);
return is2Str(post.getResponseBodyAsStream());
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
post.releaseConnection();
}
return null;
} public static Object doPosts(String url) throws UnsupportedEncodingException {
Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
Protocol.registerProtocol("https", myhttps); HttpClient client = new HttpClient();
PostMethod post = new PostMethod(url);
post.setRequestHeader("Content-Type", "application/json"); try {
client.executeMethod(post);
return is2Str(post.getResponseBodyAsStream());
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
post.releaseConnection();
}
return null;
} @SuppressWarnings("deprecation")
public static int doPosts(String url, String params, String token) throws UnsupportedEncodingException {
Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
Protocol.registerProtocol("https", myhttps); HttpClient client = new HttpClient();
PostMethod post = new PostMethod(url);
post.setRequestHeader("Content-Type", "application/json");
if (token != null) {
post.setRequestHeader("Authorization", "Bearer " + token);
}
if (params != null) {
// post.setRequestBody(params);
InputStream in = new ByteArrayInputStream(params.getBytes("utf-8"));
post.setRequestBody(in);
} try {
client.executeMethod(post);
return post.getStatusCode();
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
post.releaseConnection();
}
return 0;
} public static int doDelete(String url, String token) {
Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
Protocol.registerProtocol("https", myhttps); HttpClient client = new HttpClient();
DeleteMethod delete = new DeleteMethod(url);
if (token != null) {
delete.setRequestHeader("Authorization", "Bearer " + token);
} try {
client.executeMethod(delete);
return delete.getStatusCode();
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
delete.releaseConnection();
}
return 0;
} @SuppressWarnings("deprecation")
public static int doPuts(String url, String params, String token) throws UnsupportedEncodingException {
Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
Protocol.registerProtocol("https", myhttps); HttpClient client = new HttpClient();
PutMethod put = new PutMethod(url);
if (token != null) {
put.setRequestHeader("Authorization", "Bearer " + token);
}
if (params != null) {
// put.setRequestBody(params);
InputStream in = new ByteArrayInputStream(params.getBytes("utf-8"));
put.setRequestBody(in);
} try {
client.executeMethod(put);
return put.getStatusCode();
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
put.releaseConnection();
}
return 0;
} public static String doPost(String url, NameValuePair[] nameValuePairs) {
HttpClient client = new HttpClient();
PostMethod post = new PostMethod(url);
if (nameValuePairs != null) {
post.setRequestBody(nameValuePairs);
} try {
client.executeMethod(post);
return is2Str(post.getResponseBodyAsStream());
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
post.releaseConnection();
}
return null;
} /**
* 发送请求,创建房间
*
* @author duxin
* @param url
* 请求地址
* @param params
* 服务器需要的一个json格式的数据:包括标题,简介什么的
* @param token
* 管理员的token数据
* @return 返回一个创建好的房间结果(JSONObject格式)
* @throws UnsupportedEncodingException
*/
@SuppressWarnings("deprecation")
public static JSONObject doPostsWithToken(String url, String params, String token) throws UnsupportedEncodingException {
Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
Protocol.registerProtocol("https", myhttps);
HttpClient client = new HttpClient();
PostMethod post = new PostMethod(url);
post.setRequestHeader("Content-Type", "application/json");
if (token != null) {
post.setRequestHeader("Authorization", "Bearer " + token);
}
if (params != null) {
// post.setRequestBody(params);
InputStream in = new ByteArrayInputStream(params.getBytes("utf-8"));
post.setRequestBody(in);
} try {
client.executeMethod(post);
return is2Json(is2Str(post.getResponseBodyAsStream()));
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
post.releaseConnection();
}
return null;
} public static JSONObject is2Json(String is) throws IOException {
return JSONObject.fromObject(is);
}
}
HttpTool
重要的来了,就是环信的开发者信息:
开发者信息查看:https://console.easemob.com/index.html 登陆之后进Home主页
点击应用名称查看即可.
然后替换常量类中的数据
/**
* 环信常量保存工具类
* @author lnexin@aliyun.com
*/
public interface HuanxinConstant { public static final String CLIENT_ID = "替换自己的开发者信息,谢谢!"; public static final String CLIENT_SECRET = "替换自己的开发者信息,谢谢!"; public static final String GRANT_TYPE = "client_credentials"; public static final String HUANXIN_URL = "https://a1.easemob.com/替换自己的开发者信息,谢谢!"; public static final String TOKEN_APP_URL = HUANXIN_URL + "/token"; public static final String INITIALIZE_PASSWORD = "替换自己的开发者信息,谢谢!"; //用户体系集成url
public static final String USERS_URL = HUANXIN_URL + "/users"; //环信消息url
public static final String MESSAGES_URL = HUANXIN_URL + "/messages"; //群组url
public static final String CHATGROUPS_URL = HUANXIN_URL + "/chatgroups"; //群组消息url
public static final String CHATMESSAGES_URL = HUANXIN_URL + "/chatmessages"; //聊天室url
public static final String CHATROOM_URL = HUANXIN_URL + "/chatrooms"; }
我这个几个类扔一块的,大家各按自己喜好来.
接下来就可以使用工具类获取对应的环信聊天室ID了,这里需要向环信发送请求,然后返回ID.
如:
String chatRoomId = CreateChatRoom.createChatRooms(room.getRoomTitle() + "的聊天室", room.getRoomDesc(), room.getId(), userIds);
然后一切就搞定了.
[Java]直播方案----[接入环信聊天室]+[腾讯云直播]的更多相关文章
- ***腾讯云直播(含微信小程序直播)研究资料汇总-原创
这段时间抽空研究了下直播技术,综合比较了下腾讯云直播的技术和文档方面最齐全,现把一些技术资料和文档归集如下: 1.微信小程序移动直播入门导读 https://cloud.tencent.com/doc ...
- 微信小程序--聊天室小程序(云开发)
微信小程序 -- 聊天室小程序(云开发) 从微信小程序开发社区更新watch接口之后,一直在构思这个项目.项目已经完成很久,但是一直都没有空写一篇博客记录展示一下. 开源地址 wx-cloud-im: ...
- 微信小程序+腾讯云直播的实时音视频实战笔记
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- [转] 腾讯云直播OBS推流教程
from: http://www.jianshu.com/p/bf4066028882 腾讯云直播OBS推流教程 字数383 阅读55 评论3 喜欢0 1.安装OBS 进入obs 官网 : https ...
- 【Java】Socket+多线程实现控制台聊天室
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5827212.html 聊天室程序的结构图: 架构解释: Server服务器相当于一个中转站,Client客户端 ...
- Java利用TCP编程实现简单聊天室
前言: 本文是我在学习尚学堂JAVA300集第二季网络编程部分仿照视频内容实现而成 具体可以去尚学堂官网观看视频学习 一.实现思路 实现聊天室的最核心部分就是JAVA的TCP网络编程. TCP 传输控 ...
- 用Java构建一个简单的WebSocket聊天室
前言 首先对于一个简单的聊天室,大家应该都有一定的概念了,这里我们省略用户模块的讲解,而是单纯的先说说聊天室的几个功能:自我对话.好友交流.群聊.离线消息等. 今天我们要做的demo就能帮我们做到这一 ...
- Java 网络编程 -- 基于TCP 实现聊天室 群聊 私聊
分析: 聊天室需要多个客户端和一个服务端. 服务端负责转发消息. 客户端可以发送消息.接收消息. 消息分类: 群聊消息:发送除自己外所有人 私聊消息:只发送@的人 系统消息:根据情况分只发送个人和其他 ...
- 微信小程序 使用环信聊天工具
当时做微信小程序环信的时候,没有遇到太多的问题,因为找到了一个例子,有兴趣的朋友可以把这个包下载下来看一下,写的超级的号,使用起来也特别简单,appkey需要自己配置,从环信官网https://con ...
随机推荐
- undefined reference to symbol 'pthread_create@@GLIBC_2.2.5' 的修改方法
在编译DSO代码的时候会如下这样的问题: 检查DSO,在程序中没有用到pthread,但是在编译的时候却出现此类问题.仔细想了想了一下,在程序中用到了C++11中的线程std::thread,个人猜测 ...
- 提升Tesseract-OCR输出的质量
图片处理 修改比例(Rescaling) 二值化(Binarisation) 去除噪点(Noise Removal) 旋转/偏移校正(Rotation / Deskewing) 边界(Borders) ...
- Lua中的类型与值
[基础介绍] Lua是一种动态类型的语言.在语言中没有类型定义的语法,每个值都带有其自身的类型信息.在Lua中有8中基本类型,分别是: nil(空)类型 boolean(布尔)类型 number(数字 ...
- html5 - 地图
demo截图: demo链接 代码: <!DOCTYPE html> <html lang="en"> <head> <meta char ...
- Linux -- Xshell ,Xftp远程连接中文乱码怎么解决?
### 这几天开始捣鼓lnmp的环境搭建,很多东西还是得自己去经历,才会印象深刻,有所体会,有所收获与成长! 但是,偶尔会遇到一些意想不到问题! Xshell ,Xftp 远程连接的时候出现中文乱码的 ...
- Codeforces 1083C Max Mex [线段树]
洛谷 Codeforces 思路 很容易发现答案满足单调性,可以二分答案. 接下来询问就转换成判断前缀点集是否能组成一条链. 我最初的想法:找到点集的直径,判断直径是否覆盖了所有点,需要用到树套树,复 ...
- Java实现大数加法运算的几种方法
大数加法 思路一:定义String变量str1和str2分别存储输入的两个大数,定义num1[]和num2[]两个int型数组,将两个字符串分别逐个字符逆序存入数组,定义sum[]数组存放求和结果,使 ...
- P2947 [USACO09MAR]向右看齐Look Up--单调栈
单调栈真的很好用呢! P2947 [USACO09MAR]向右看齐Look Up 题目描述 Farmer John's N (1 <= N <= 100,000) cows, conven ...
- 4.9cf自训9..
cf401D 状态压缩dp好题,每次把新加入集合的数字放在最后即可 /* 它可以通过重新排列数字n, 它没有任何前导零, x除以m后的余数等于0. 每次把新加的数放在最后 dp[i][j]表示状态i下 ...
- php判断是不是手机端访问
最笨方法自己亲测! if (isset($_SERVER['HTTP_USER_AGENT'])) { $clientkeywords = array('iphone', 'android', 'ph ...