package com.state;
/**
* 临时容器
* @author Allen 2017年3月31日
*
*/
import java.util.HashMap;
import com.state.room.RoomVo;
public class Ram {
public static HashMap roomHm = new HashMap<>();
}
package com.state.user;
public class UserVo implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = -6628674875994109212L;
private String red5Id;
private String red5Name;
private Long red5CreateTime;
public String getRed5Id() {
return red5Id;
}
public void setRed5Id(String red5Id) {
this.red5Id = red5Id;
}
public String getRed5Name() {
return red5Name;
}
public void setRed5Name(String red5Name) {
this.red5Name = red5Name;
}
public Long getRed5CreateTime() {
return red5CreateTime;
}
public void setRed5CreateTime(Long red5CreateTime) {
this.red5CreateTime = red5CreateTime;
}
}
package com.state.user;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import com.state.Ram;
/**
* 用户操作
*
* @author Allen 2017年3月31日
*
*/
public class UserState {
/**
* 插入用户到房间中
* @param red5Id
* @param red5Name
* @param red5CreateTime
* @param roomKey
* @return
*/
public boolean insert(String red5Id, String red5Name, Long red5CreateTime, String roomKey) {
try {
if (Ram.roomHm.containsKey(roomKey)) {
UserVo uvo = new UserVo();
uvo.setRed5Id(red5Id);
uvo.setRed5Name(red5Name);
uvo.setRed5CreateTime(red5CreateTime);
Ram.roomHm.get(roomKey).getUserList().add(uvo);
return true;
}
selectAll(roomKey);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 获取房间中全部用户
* @param roomKey
* @return
*/
public List selectAll(String roomKey) {
try {
if (Ram.roomHm.containsKey(roomKey)) {
Iterator it = Ram.roomHm.get(roomKey).getUserList().iterator();
System.out.println("================================================");
while (it.hasNext()) {
UserVo temp = it.next();
System.out.println(temp.getRed5Id() + "," + temp.getRed5Name() + ","
+ new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date(temp.getRed5CreateTime())));
}
System.out.println("================================================");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 删除房间中某用户
* @param redId
* @param roomKey
* @return
*/
public boolean delete(String redId, String roomKey) {
try {
if (Ram.roomHm.containsKey(roomKey)) {
Iterator it = Ram.roomHm.get(roomKey).getUserList().iterator();
while (it.hasNext()) {
if (it.next().getRed5Id().equals(redId))
{
it.remove();
break;
}
}
}
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 统计房间中用户数
* @param roomKey
* @return
*/
public int count(String roomKey) {
return Ram.roomHm.containsKey(roomKey) ? Ram.roomHm.get(roomKey).getUserList().size() : 0;
}
}
package com.state.room;
import java.util.ArrayList;
import java.util.List;
import com.state.user.UserVo;
/**
* 房间VO
*
* @author Allen 2017年3月31日
*
*/
public class RoomVo {
private String roomKey;// 房间key
private String roomName;// 房间名
private List userList=new ArrayList<>();// 房间内用户列表
public List getUserList() {
return userList;
}
public void setUserList(List userList) {
this.userList = userList;
}
public String getRoomKey() {
return roomKey;
}
public void setRoomKey(String roomKey) {
this.roomKey = roomKey;
}
public String getRoomName() {
return roomName;
}
public void setRoomName(String roomName) {
this.roomName = roomName;
}
}
package com.state.room;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import com.state.Ram;
/**
* 房间操作
*
* @author Allen 2017年3月31日
*
*/
public class RoomState {
/**
* 创建一个房间信息
*
* @param roomKey
* @param roomName
* @return
*/
public boolean insert(String roomKey, String roomName) {
try {
if (!Ram.roomHm.containsKey(roomKey)) {
RoomVo rVo = new RoomVo();
rVo.setRoomName(roomName);
Ram.roomHm.put(roomKey, rVo);
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 返回所有房间信息
*
* @return
*/
public List selectAll() {
try {
List resultList = new ArrayList<>();
Iterator> it = Ram.roomHm.entrySet().iterator();
while (it.hasNext()) {
Entry entry = it.next();
resultList.add(entry.getValue());
}
return resultList;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 删除一个房间信息
*
* @param red5Id
* @return
*/
public boolean delete(String roomKey) {
try {
Ram.roomHm.remove(roomKey);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 统计房间总数
*
* @return
*/
public int count() {
return Ram.roomHm.size();
}
}
package com.service;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.red5.server.adapter.MultiThreadedApplicationAdapter;
import org.red5.server.api.IClient;
import org.red5.server.api.IConnection;
import org.red5.server.api.scope.IScope;
import org.red5.server.api.stream.IBroadcastStream;
import org.red5.server.api.stream.ISubscriberStream;
import com.state.room.RoomState;
import com.state.user.UserState;
/**
*
* @author Allen 2017年4月7日
*
*/
public class Application extends MultiThreadedApplicationAdapter {
@Override
public boolean connect(IConnection conn) {
System.out.println("connect");
return super.connect(conn);
}
@Override
public void disconnect(IConnection arg0, IScope arg1) {
System.out.println("disconnect");
new UserState().delete(arg0.getSessionId(), arg0.getAttribute(arg0.getSessionId()).toString());
super.disconnect(arg0, arg1);
}
/**
* 开始发布直播
*/
@Override
public void streamPublishStart(IBroadcastStream stream) {
System.out.println("[streamPublishStart]********** ");
System.out.println("发布Key: " + stream.getPublishedName());
RoomState room = new RoomState();
room.insert(stream.getPublishedName(), "房间" + stream.getPublishedName());
System.out.println(
"发布时间:" + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date(stream.getCreationTime())));
System.out.println("****************************** ");
}
/**
* 流结束
*/
@Override
public void streamBroadcastClose(IBroadcastStream arg0) {
RoomState room = new RoomState();
room.delete(arg0.getPublishedName());
super.streamBroadcastClose(arg0);
}
/**
* 用户断开播放
*/
@Override
public void streamSubscriberClose(ISubscriberStream arg0) {
new UserState().delete(arg0.getConnection().getSessionId(), arg0.getBroadcastStreamPublishName());
super.streamSubscriberClose(arg0);
}
/**
* 链接rtmp服务器
*/
@Override
public boolean appConnect(IConnection arg0, Object[] arg1) {
// TODO Auto-generated method stub
System.out.println("[appConnect]********** ");
System.out.println("请求域:" + arg0.getScope().getContextPath());
System.out.println("id:" + arg0.getClient().getId());
System.out.println("name:" + arg0.getClient().getId());
System.out.println("**************** ");
return super.appConnect(arg0, arg1);
}
/**
* 加入了rtmp服务器
*/
@Override
public boolean join(IClient arg0, IScope arg1) {
// TODO Auto-generated method stub
return super.join(arg0, arg1);
}
/**
* 开始播放流
*/
@Override
public void streamSubscriberStart(ISubscriberStream stream) {
System.out.println("[streamSubscriberStart]********** ");
System.out.println("播放域:" + stream.getScope().getContextPath());
System.out.println("播放Key:" + stream.getBroadcastStreamPublishName());
System.out.println("********************************* ");
String sessionId = stream.getConnection().getSessionId();
stream.getConnection().setAttribute(null, null);
new UserState().insert(sessionId, sessionId, stream.getCreationTime(), stream.getBroadcastStreamPublishName());
super.streamSubscriberStart(stream);
}
/**
* 离开了rtmp服务器
*/
@Override
public void leave(IClient arg0, IScope arg1) {
System.out.println("leave");
super.leave(arg0, arg1);
}
}
[appConnect]**********
请求域:/liveOnline
id:1
name:1
****************
注意一下:Spring jar包我们放到WEB-INF/libs 中,然后引用它,这里如果使用默认的lib目录,最后发布red5+springMVC的时候red5的rtmp会无法访问,会抛出Scope not found!!!!虽然这个问题在google百度github都没有解释,但是我最后还是找到的解决方案!如果你用lib没有问题,那么只能说是系统环境了。。我用的是win7 64bit。linux或者mac或许没问题吧
首先我们把WEB-INF 下面的lib改成libs,如果没有lib新建一个libs即可
我们将spring的jar包拷贝到libs,为什么选择4.3.6因为我的red5 server下lib中的spring就是4.3.6的保持版本与red5一致!
Add JARS到项目
springDispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
/WEB-INF/springmvc.xml
2
springDispatcherServlet
/*
default
*.css
default
*.gif
default
*.jpg
default
*.js
default
*.html
package com.action.room;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.state.Ram;
/**
*
* @author Allen 2017年4月10日
*
*/
@Controller
public class room {
@ResponseBody
@RequestMapping("/roomsize")
public String hello() {
return "当前房间数: "+Ram.roomHm.size() ;
}
}