2021SC@SDUSC
软件工程应用与实践——OpenMeetings项目分析(五):
本周,继续进行util包下其他子类的分析;
上周分析至filewebservice.java,是有关于视频会议过程中的文件上传有关的网络服务类,本周从GroupWebService.java开始分析:
GroupWebService.java
先贴上源码:
@Service("groupWebService")
@WebService(serviceName="org.apache.openmeetings.webservice.GroupWebService", targetNamespace = TNS)
@Features(features = "org.apache.cxf.ext.logging.LoggingFeature")
@Produces({MediaType.APPLICATION_JSON})
@Path("/group")
public class GroupWebService extends BaseWebService {
private static final Logger log = Red5LoggerFactory.getLogger(GroupWebService.class, getWebAppRootKey());
private static GroupDao getDao() {
return getBean(GroupDao.class);
}
@POST
@Path("/")
public ServiceResult add(@QueryParam("sid") @WebParam(name="sid") String sid, @QueryParam("name") @WebParam(name="name") String name) {
log.debug("add:: name {}", name);
return performCall(sid, User.Right.Soap, sd -> {
Group o = new Group();
o.setName(name);
return new ServiceResult(String.valueOf(getDao().update(o, sd.getUserId()).getId()), Type.SUCCESS);
});
}
@GET
@Path("/")
public List<GroupDTO> get(@QueryParam("sid") @WebParam(name="sid") String sid) {
return performCall(sid, User.Right.Soap, sd -> GroupDTO.list(getDao().get(0, Integer.MAX_VALUE)));
}
@POST
@Path("/{id}/users/{userid}")
public ServiceResult addUser(
@QueryParam("sid") @WebParam(name="sid") String sid
, @PathParam("id") @WebParam(name="id") Long id
, @PathParam("userid") @WebParam(name="userid") Long userid
)
{
return performCall(sid, User.Right.Soap, sd -> {
if (!getBean(GroupUserDao.class).isUserInGroup(id, userid)) {
UserDao userDao = getUserDao();
User u = userDao.get(userid);
u.getGroupUsers().add(new GroupUser(getDao().get(id), u));
userDao.update(u, sd.getUserId());
}
return new ServiceResult(String.valueOf(userid), Type.SUCCESS);
});
}
@DELETE
@Path("/{id}/users/{userid}")
public ServiceResult removeUser(
@QueryParam("sid") @WebParam(name="sid") String sid
, @PathParam("id") @WebParam(name="id") Long id
, @PathParam("userid") @WebParam(name="userid") Long userid
)
{
return performCall(sid, User.Right.Soap, sd -> {
if (getBean(GroupUserDao.class).isUserInGroup(id, userid)) {
UserDao userDao = getUserDao();
User u = userDao.get(userid);
for (Iterator<GroupUser> iter = u.getGroupUsers().iterator(); iter.hasNext(); ) {
GroupUser gu = iter.next();
if (id.equals(gu.getGroup().getId())) {
iter.remove();
}
}
userDao.update(u, sd.getUserId());
}
return new ServiceResult(String.valueOf(userid), Type.SUCCESS);
});
}
@POST
@Path("/{id}/rooms/add/{roomid}")
public ServiceResult addRoom(
@QueryParam("sid") @WebParam(name="sid") String sid
, @PathParam("id") @WebParam(name="id") Long id
, @PathParam("roomid") @WebParam(name="roomid") Long roomid
)
{
return performCall(sid, User.Right.Soap, sd -> {
RoomDao roomDao = getRoomDao();
Room r = roomDao.get(roomid);
if (r != null) {
if (r.getGroups() == null) {
r.setGroups(new ArrayList<RoomGroup>());
}
boolean found = false;
for (RoomGroup ro : r.getGroups()) {
if (ro.getGroup().getId().equals(id)) {
found = true;
}
}
if (!found) {
r.getGroups().add(new RoomGroup(getDao().get(id), r));
roomDao.update(r, sd.getUserId());
return new ServiceResult("Success", Type.SUCCESS);
}
}
return new ServiceResult("Not added", Type.ERROR);
});
}
@GET
@Path("/users/{id}")
public UserSearchResult getUsers(
@QueryParam("sid") @WebParam(name="sid") String sid
, @PathParam("id") @WebParam(name="id") long id
, @QueryParam("start") @WebParam(name="start") int start
, @QueryParam("max") @WebParam(name="max") int max
, @QueryParam("orderby") @WebParam(name="orderby") String orderby
, @QueryParam("asc") @WebParam(name="asc") boolean asc
)
{
return performCall(sid, User.Right.Soap, sd -> {
SearchResult<User> result = new SearchResult<>();
result.setObjectName(User.class.getName());
GroupUserDao dao = getBean(GroupUserDao.class);
result.setRecords(dao.count(id));
result.setResult(new ArrayList<User>());
String order = isAlphanumeric(orderby) ? orderby : "id";
for (GroupUser ou : dao.get(id, null, start, max, order + " " + (asc ? "ASC" : "DESC"))) {
result.getResult().add(ou.getUser());
}
return new UserSearchResult(result);
});
}
@WebMethod
@DELETE
@Path("/{id}")
public ServiceResult delete(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="id") @PathParam("id") long id) {
return performCall(sid, User.Right.Admin, sd -> {
GroupDao dao = getDao();
dao.delete(dao.get(id), sd.getUserId());
return new ServiceResult("Deleted", Type.SUCCESS);
});
}
}
首先,观察此类的结构:
包含一个成员变量Logger类型的log,以及数个公有方法和一个私有方法,和上周分析的数个webservice项目类似;
该服务类继承自BaseWebServicel类,包含登录和创建哈希以直接进入会议室、录音或一般应用程序的方法;下面进行方法的分析:
getDao方法:
类似之前,得到一个GroupDao类型的对象,以便作为参数供其他成员函数调用;
add方法:
添加一个新组
形参:
sid – 来自 getSession取到的session里的 SID
名称 - 组的名称
返回值:
带有结果类型和添加组 ID 的ServiceResult
get方法:
获取所有组的列表
形参:
sid – 来自 getSession 的 SID
返回值:
所有组的列表
addUser方法:
将用户添加到某个组
形参:
sid – 来自 getSession 的 SID
id – 组 ID
userid – 用户 ID
返回值:
带有结果类型的ServiceResult和添加的用户的 id,或者在错误为文本的情况下的错误 id
removeUser方法
从特定组中删除用户
形参:
sid – 来自 getSession 的 SID
id – 组 ID
userid – 用户 ID
返回值:
带有结果类型的ServiceResult和添加的用户的 id,或者在错误为文本的情况下的错误 id
addRoom方法:
将房间添加到组
形参:
sid - - 用户的 SID。 此 SID 必须标记为已登录
id – - 与房间配对的组的 ID
roomid – - 要添加的房间的 ID
返回值:
带有结果类型的ServiceResult
getUsers方法:
搜索用户并返回他们
形参:
sid – 来自 getSession 的 SID
id – 组 ID
开始——第一条记录
最大 - 最大记录
orderby – orderby 子句
asc – 升序或降序
返回值:用户发现
delete方法:
删除一个组
形参:
sid – 用户的 SID。 此 SID 必须标记为已登录
id - 组的 ID
返回值:
带有结果类型的ServiceResult
小结:
此服务类是用于组管理的,通过getDao方法取到groupDao类型的对象后,进行组管理的各种操作;
InfoWebService.java
@Service("infoWebService")
@WebService(serviceName="org.apache.openmeetings.webservice.InfoWebService", targetNamespace = TNS)
@Features(features = "org.apache.cxf.ext.logging.LoggingFeature")
@Produces({MediaType.APPLICATION_JSON})
@Path("/info")
public class InfoWebService {
@WebMethod
@GET
@Path("/version")
public Info getVersion() {
return new Info();
}
@WebMethod
@GET
@Path("/health")
public Health getHealth() {
return Health.INSTANCE;
}
}
此类代码量较少,结构比较简单直接分析即可;
InfoWebService继承自BaseWbeService,主要用于获取系统信息,(即openmeetings的版本号等信息)
getVersion方法:
如上所述,用于获取openmeetings的版本,返回的是一个自定义的info类型,位于org.apache.openmeetings.db.dto.basic包下;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Info implements Serializable {
private static final long serialVersionUID = 1L;
private final String version;
private final String revision;
private final String buildDate;
public Info() {
version = Version.getVersion();
revision = Version.getRevision();
buildDate = Version.getBuildDate();
}
public String getVersion() {
return version;
}
public String getRevision() {
return revision;
}
public String getBuildDate() {
return buildDate;
}
}
info类继承了serializable接口实现了序列化,包含了4个属性以及一个构造方法,三个get方法,非常简单。
getHealth方法:
用于获取此 OpenMeetings 项目的运行情况报告,返回值是一个health(也是org.apache.openmeetings.db.dto.basic包下的)
NetTestWebService.java
@Service("netTestWebService")
@Path("/networktest")
public class NetTestWebService {
private static final Logger log = Red5LoggerFactory.getLogger(UserWebService.class, getWebAppRootKey());
enum TestType {
UNKNOWN,
PING,
JITTER,
DOWNLOAD_SPEED,
UPLOAD_SPEED
}
private static final int PING_PACKET_SIZE = 64;
private static final int JITTER_PACKET_SIZE = 1024;
private static final int DOWNLOAD_PACKET_SIZE = 1024*1024;
private final byte[] pingData;
private final byte[] jitterData;
private final byte[] downloadData;
public NetTestWebService() {
pingData = new byte[PING_PACKET_SIZE];
jitterData = new byte[JITTER_PACKET_SIZE];
downloadData = new byte[DOWNLOAD_PACKET_SIZE];
Arrays.fill(pingData, (byte) '0');
Arrays.fill(jitterData, (byte) '0');
Arrays.fill(downloadData, (byte) '0');
}
@GET
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Path("/")
public Response get(@QueryParam("type") String type) {
TestType testType = getTypeByString(type);
log.debug("Network test:: get");
// choose data to send
byte[] data = new byte[0];
switch (testType) {
case PING:
data = pingData;
break;
case JITTER:
data = jitterData;
break;
case DOWNLOAD_SPEED:
data = downloadData;
break;
case UPLOAD_SPEED:
break;
default:
break;
}
ResponseBuilder response = Response.ok().type(MediaType.APPLICATION_OCTET_STREAM).entity(new ByteArrayInputStream(data));
response.header("Cache-Control", "no-cache");
response.header("Content-Length", String.valueOf(data.length));
return response.build();
}
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/")
public void upload(@Multipart(value = "stream", type = MediaType.APPLICATION_OCTET_STREAM) InputStream stream) throws IOException {
byte[] b = new byte[1024];
while (stream.read(b) >= 0 ) {
//no-op
};
}
private static TestType getTypeByString(String typeString) {
if ("ping".equals(typeString)) {
return TestType.PING;
} else if ("jitter".equals(typeString)) {
return TestType.JITTER;
} else if ("download".equals(typeString)) {
return TestType.DOWNLOAD_SPEED;
} else if ("upload".equals(typeString)) {
return TestType.UPLOAD_SPEED;
}
return TestType.UNKNOWN;
}
}
顾名思义,此类是用来检查网络连接情况的,包括数个常量,以及两个公有方法一个私有方法,还有一个枚举类型的变量;
构造函数负责对成员变量进行初始化;
get方法:
得到发送测试数据的结果
形参:
type,测试发送数据的方式
返回值:
带有结果类型的Response
upload方法:
上传方法,创建了缓冲区,根据传入的输入流测试上传
形参:
stream 一个输入流类型得形参
返回值:
void
RecordingWebService.java
@Service("recordWebService")
@WebService(serviceName="org.apache.openmeetings.webservice.RecordingWebService", targetNamespace = TNS)
@Features(features = "org.apache.cxf.ext.logging.LoggingFeature")
@Produces({MediaType.APPLICATION_JSON})
@Path("/record")
public class RecordingWebService extends BaseWebService {
private static final Logger log = Red5LoggerFactory.getLogger(RecordingWebService.class, getWebAppRootKey());
private static RecordingDao getDao() {
return getBean(RecordingDao.class);
}
@DELETE
@Path("/{id}")
public ServiceResult delete(@QueryParam("sid") @WebParam(name="sid") String sid, @PathParam("id") @WebParam(name="id") Long id) {
return performCall(sid, User.Right.Soap, sd -> {
RecordingDao dao = getDao();
dao.delete(dao.get(id));
return new ServiceResult("Deleted", Type.SUCCESS);
});
}
@WebMethod
@GET
@Path("/{externaltype}/{externalid}")
public List<RecordingDTO> getExternal(@WebParam(name="sid") @QueryParam("sid") String sid
, @PathParam("externaltype") @WebParam(name="externaltype") String externalType
, @PathParam("externalid") @WebParam(name="externalid") String externalId) {
log.debug("getExternal:: type {}, id {}", externalType, externalId);
return performCall(sid, User.Right.Soap, sd -> RecordingDTO.list(getDao().getByExternalId(externalId, externalType)));
}
@WebMethod
@GET
@Path("/{externaltype}")
public List<RecordingDTO> getExternalByType(@WebParam(name="sid") @QueryParam("sid") String sid
, @PathParam("externaltype") @WebParam(name="externaltype") String externalType) {
return performCall(sid, User.Right.Soap, sd -> RecordingDTO.list(getDao().getByExternalType(externalType)));
}
@WebMethod
@GET
@Path("/room/{roomid}")
public List<RecordingDTO> getExternalByRoom(@WebParam(name="sid") @QueryParam("sid") String sid
, @PathParam("roomid") @WebParam(name="roomid") Long roomId) {
return performCall(sid, User.Right.Soap, sd -> RecordingDTO.list(getDao().getByRoomId(roomId)));
}
}
此类主要用于处理录音,包含一系列方法
getDao方法:
返回对应此类的Dao类型得对象,类似之前几个类
delete方法:
删除一个 flv 录音
形参:
sid – 用户的 SID。 此 SID 必须标记为已登录
id – 录音的 id
返回值:
带有结果类型的ServiceResult
getExternal方法:
获取 flv 录音列表
形参:
sid – 用户的 SID。 此 SID 必须标记为已登录
externalType – externalUserType
externalId – externalUserId
返回值:
flv 录音列表
getExternalByType方法:
获取 flv 录音列表
形参:
sid – 用户的 SID。 此 SID 必须标记为已登录
externalType – 创建房间时指定的 externalType
返回值:
flv 录音列表
getExternalByRoom方法:
获取录音列表
形参:
sid – 用户的 SID。 此 SID 必须标记为已登录
roomId – 房间 ID
返回值:
录音列表
小结:
此类定义了一系列用于处理会议录音的方法,可以通过录音id以及录音所在的控制台id对其进行管理
RoomWebService.java
@Service("roomWebService")
@WebService(serviceName="org.apache.openmeetings.webservice.RoomWebService", targetNamespace = TNS)
@Features(features = "org.apache.cxf.ext.logging.LoggingFeature")
@Produces({MediaType.APPLICATION_JSON})
@Path("/room")
public class RoomWebService extends BaseWebService {
private static final Logger log = Red5LoggerFactory.getLogger(RoomWebService.class, getWebAppRootKey());
@WebMethod
@GET
@Path("/public/{type}")
public List<RoomDTO> getPublic(@QueryParam("sid") @WebParam(name="sid") String sid, @PathParam("type") @WebParam(name="type") String type) {
Room.Type t = Strings.isEmpty(type) ? null : Room.Type.valueOf(type);
return performCall(sid, User.Right.Room, sd -> RoomDTO.list(getRoomDao().getPublicRooms(t)));
}
@WebMethod
@GET
@Path("/{id}")
public RoomDTO getRoomById(@QueryParam("sid") @WebParam(name="sid") String sid, @PathParam("id") @WebParam(name="id") Long id) {
return performCall(sid, User.Right.Soap, sd -> new RoomDTO(getRoomDao().get(id)));
}
private static Room updateRtoRoom(Room r, Long userId) {
if (r.getFiles() == null) {
r.setFiles(new ArrayList<>());
}
RoomDao roomDao = getRoomDao();
if (r.getId() == null) {
List<RoomFile> files = r.getFiles();
r.setFiles(null);
r = roomDao.update(r, userId);
r.setFiles(files);
}
for (RoomFile rf : r.getFiles()) {
rf.setRoomId(r.getId());
}
return roomDao.update(r, userId);
}
@WebMethod
@GET
@Path("/{type}/{externaltype}/{externaliId}")
public RoomDTO getExternal(@WebParam(name="sid") @QueryParam("sid") String sid
, @PathParam("type") @WebParam(name="type") String type
, @PathParam("externaltype") @WebParam(name="externaltype") String externalType
, @PathParam("externalid") @WebParam(name="externalid") String externalId
, @WebParam(name="room") @QueryParam("room") RoomDTO room) {
return performCall(sid, User.Right.Soap, sd -> {
RoomDao roomDao = getRoomDao();
Room r = roomDao.getExternal(Room.Type.valueOf(type), externalType, externalId);
if (r == null) {
if (room == null) {
return null;
} else {
r = room.get(getFileDao());
r.setExternalType(externalType);
r.setExternalId(externalId);
r = updateRtoRoom(r, sd.getUserId());
return new RoomDTO(r);
}
} else {
return new RoomDTO(r);
}
});
}
@WebMethod
@POST
@Path("/")
public RoomDTO add(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="room") @FormParam("room") RoomDTO room) {
return performCall(sid, User.Right.Soap, sd -> {
Room r = room.get(getFileDao());
r = updateRtoRoom(r, sd.getUserId());
return new RoomDTO(r);
});
}
@WebMethod
@DELETE
@Path("/{id}")
public ServiceResult delete(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="id") @PathParam("id") long id) {
return performCall(sid, User.Right.Soap, sd -> {
RoomDao roomDao = getRoomDao();
Room r = roomDao.get(id);
if (r == null) {
return new ServiceResult("Not found", Type.SUCCESS);
} else {
roomDao.delete(r, sd.getUserId());
return new ServiceResult("Deleted", Type.SUCCESS);
}
});
}
@WebMethod
@GET
@Path("/close/{id}")
public ServiceResult close(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="id") @PathParam("id") long id) {
return performCall(sid, User.Right.Soap, sd -> {
Long userId = sd.getUserId();
RoomDao roomDao = getRoomDao();
Room room = roomDao.get(id);
room.setClosed(true);
roomDao.update(room, userId);
WebSocketHelper.sendRoom(new RoomMessage(room.getId(), getUserDao().get(userId), RoomMessage.Type.roomClosed));
return new ServiceResult("Closed", Type.SUCCESS);
});
}
@WebMethod
@GET
@Path("/open/{id}")
public ServiceResult open(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="id") @PathParam("id") long id) {
return performCall(sid, User.Right.Soap, sd -> {
RoomDao roomDao = getRoomDao();
Room room = roomDao.get(id);
room.setClosed(false);
roomDao.update(room, sd.getUserId());
return new ServiceResult("Opened", Type.SUCCESS);
});
}
@WebMethod
@GET
@Path("/kick/{id}")
public ServiceResult kickAll(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="id") @PathParam("id") long id) {
return performCall(sid, User.Right.Soap, sd -> {
boolean result = getBean(IUserManager.class).kickUsersByRoomId(id);
return new ServiceResult(result ? "Kicked" : "Not kicked", Type.SUCCESS);
});
}
@WebMethod
@GET
@Path("/kick/{id}/{externalType}/{externalId}")
public ServiceResult kick(@WebParam(name="sid") @QueryParam("sid") String sid
, @WebParam(name="id") @PathParam("id") long id
, @WebParam(name="externalType") @PathParam("externalType") String externalType
, @WebParam(name="externalId") @PathParam("externalId") String externalId)
{
return performCall(sid, User.Right.Soap, sd -> {
boolean result = getBean(IUserManager.class).kickExternal(id, externalType, externalId);
return new ServiceResult(result ? "Kicked" : "Not kicked", Type.SUCCESS);
});
}
@WebMethod
@GET
@Path("/count/{roomid}")
public ServiceResult count(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="roomid") @PathParam("roomid") Long roomId) {
return performCall(sid, User.Right.Soap, sd -> new ServiceResult(String.valueOf(getBean(IClientManager.class).listByRoom(roomId).size()), Type.SUCCESS));
}
@WebMethod
@GET
@Path("/users/{roomid}")
public List<UserDTO> users(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="roomid") @PathParam("roomid") Long roomId) {
return performCall(sid, User.Right.Soap, sd -> {
List<UserDTO> result = new ArrayList<>();
for (Client c : getBean(IClientManager.class).listByRoom(roomId)) {
result.add(new UserDTO(c.getUser()));
}
return result;
});
}
@WebMethod
@POST
@Path("/hash")
public ServiceResult hash(@WebParam(name="sid") @QueryParam("sid") String sid
, @WebParam(name="invite") @QueryParam("invite") InvitationDTO invite
, @WebParam(name="sendmail") @QueryParam("sendmail") boolean sendmail
)
{
log.debug("[hash] invite {}", invite);
return performCall(sid, User.Right.Soap, sd -> {
Invitation i = invite.get(sd.getUserId(), getUserDao(), getRoomDao());
i = getBean(InvitationDao.class).update(i);
if (i != null) {
if (sendmail) {
try {
getBean(InvitationManager.class).sendInvitationLink(i, MessageType.Create, invite.getSubject(), invite.getMessage(), false);
} catch (Exception e) {
throw new ServiceException(e.getMessage());
}
}
return new ServiceResult(i.getHash(), Type.SUCCESS);
} else {
return new ServiceResult("error.unknown", Type.ERROR);
}
});
}
@WebMethod
@GET
@Path("/cleanwb/{id}")
public ServiceResult cleanWb(@WebParam(name="sid") @QueryParam("sid") String sid
, @WebParam(name="id") @PathParam("id") long id
)
{
log.debug("[cleanwb] room id {}", id);
return performCall(sid, User.Right.Soap, sd -> {
getBean(IWhiteboardManager.class).remove(id);
return new ServiceResult("", Type.SUCCESS);
});
}
}
项目结构:
RoomWebService类主要用于操作房间和创建邀请哈希链接
getPublic方法:
返回一个包含房间对象列表的房间列表类型的对象。 每个房间对象都包含一个房间类型和有关该房间的所有信息。 如果您通过 SOAP 获取房间中当前用户的列表,则它们为 Null。 房间类型可以是“会议”、“演示”或“采访”。
形参:
sid – 用户的 SID。 此 SID 必须标记为已登录
type – 需要检索的公共房间类型
返回值:
公共房间列表
getRoomById方法:
返回会议室对象
形参:
sid - - 用户的 SID。 此 SID 必须标记为已登录
id - - 房间ID
返回值:
给定 id 的房间
updateRtoRoom方法:
此方法需要在房间子对象上设置其他字段,例如:RoomFile.roomId
形参:
r 一个房间类型的引用
userId额外的一个用户id
返回值:对房间进行添加操作后的room类型对象
getExternal方法:
检查具有此exteralRoomId + externalRoomType 的房间是否存在,如果存在则返回房间id,否则将创建房间,然后返回新创建房间的房间id
形参:
sid – 用户的 SID。 此 SID 必须标记为已登录
类型 - 房间类型
externalType – 您可以在此处指定您的系统名称或房间类型,例如“moodle”
externalId – 您的外部房间 ID 可以在此处设置
房间 - 如果找不到要创建的房间的详细信息
返回值:
房间ID或错误代码
add方法:
像通过前端一样添加一个新房间
形参:
sid – 来自 getSession 的 SID
房间 – 房间对象
返回值:
添加的用户 ID 或错误代码
delete方法:
按房间 id 删除房间
形参:
sid - - 用户的 SID。 此 SID 必须标记为已登录
id - - 房间的id
返回值:
房间的ID被删除
close方法:
远程关闭房间的方法。 如果房间被关闭,房间内的所有用户和所有试图进入它的用户都将被重定向到 Room-Object 中定义的 redirectURL。 如果身份验证成功,则返回正值。
形参:
sid – 用户的 SID。 此 SID 必须标记为已登录
id – 房间 ID
返回值:
1 成功,-2 否则
open 方法:
远程打开房间的方法。 如果房间被关闭,房间内的所有用户和所有试图进入它的用户都将被重定向到 Room-Object 中定义的 redirectURL。 如果身份验证成功,则返回正值。
形参:
sid – 用户的 SID。 此 SID 必须标记为已登录
id – 房间 ID
返回值:
1 成功,-2 否则
kickAll方法:
踢掉某个房间的所有用途
形参:
sid – 用户的 SID。 此 SID 必须标记为 Loggedin _Admin
id – 房间 ID
返回值:
如果用户被踢,则为真,否则为假
kick方法:
从给定房间踢外部用户
形参:
sid – 用户的 SID。 此 SID 必须标记为 Loggedin _Admin
id – 房间 ID
externalType – 要踢的外部用户类型
externalId – 要踢的用户的外部 ID
返回值:
如果用户被踢,则为真,否则为假
count 方法:
返回当前房间中具有给定 id 的用户数
形参:
sid – 来自 UserService.getSession 的 SID
roomId – 获取用户的房间 ID
返回值:
用户数作为 int
users方法:
返回当前在房间中具有给定 id 的用户列表
形参:
sid – 来自 UserService.getSession 的 SID
roomId – 获取用户的房间 ID
返回值:
房间内的用户List
hash方法:
使用给定参数获取邀请哈希的方法
形参:
sid - - 用户的 SID。 此 SID 必须标记为已登录
invite- - 邀请的参数
sendmail – - 确定是否应该发送电子邮件的标志
返回值:
带有结果的 serviceResult 对象
cleanWb方法:
清理房间白板的方法(将清除所有对象)
形参:
sid - - 用户的 SID。 此 SID 必须标记为已登录
id - - 要打扫的房间的 id
返回值:
带有结果的 serviceResult 对象
小结:
此类代码量较大,包含一系列对开会房间进行操作的方法,以及添加,删除人员,远程打开关闭会议室,清理白板等重要方法,非常重要。
UserWebService.java
@Service("userWebService")
@WebService(serviceName = USER_SERVICE_NAME, targetNamespace = TNS, portName = USER_SERVICE_PORT_NAME)
@Features(features = "org.apache.cxf.ext.logging.LoggingFeature")
@Produces({MediaType.APPLICATION_JSON})
@Path("/user")
public class UserWebService extends BaseWebService {
private static final Logger log = Red5LoggerFactory.getLogger(UserWebService.class, getWebAppRootKey());
@WebMethod
@GET
@Path("/login")
public ServiceResult login(@WebParam(name="user") @QueryParam("user") String user, @WebParam(name="pass") @QueryParam("pass") String pass) {
try {
log.debug("Login user");
User u = getUserDao().login(user, pass);
if (u == null) {
return new ServiceResult("error.bad.credentials", Type.ERROR);
}
Sessiondata sd = getSessionDao().create(u.getId(), u.getLanguageId());
log.debug("Login user: {}", u.getId());
return new ServiceResult(sd.getSessionId(), Type.SUCCESS);
} catch (OmException oe) {
return oe.getKey() == null ? UNKNOWN : new ServiceResult(oe.getKey(), Type.ERROR);
} catch (Exception err) {
log.error("[login]", err);
return UNKNOWN;
}
}
@WebMethod
@GET
@Path("/")
public List<UserDTO> get(@WebParam(name="sid") @QueryParam("sid") String sid) {
return performCall(sid, User.Right.Soap, sd -> UserDTO.list(getUserDao().getAllUsers()));
}
@WebMethod
@POST
@Path("/")
public UserDTO add(
@WebParam(name="sid") @QueryParam("sid") String sid
, @WebParam(name="user") @FormParam("user") UserDTO user
, @WebParam(name="confirm") @FormParam("confirm") Boolean confirm
)
{
return performCall(sid, User.Right.Soap, sd -> {
UserDao userDao = getUserDao();
if (!isAllowRegisterSoap()) {
throw new ServiceException("Soap register is denied in Settings");
}
User testUser = userDao.getExternalUser(user.getExternalId(), user.getExternalType());
if (testUser != null) {
throw new ServiceException("User does already exist!");
}
String tz = user.getTimeZoneId();
if (Strings.isEmpty(tz)) {
tz = getDefaultTimezone();
}
if (user.getAddress() == null) {
user.setAddress(new Address());
user.getAddress().setCountry(Locale.getDefault().getCountry());
}
if (user.getLanguageId() == null) {
user.setLanguageId(1L);
}
IValidator<String> passValidator = new StrongPasswordValidator(true, user.get(userDao));
Validatable<String> passVal = new Validatable<>(user.getPassword());
passValidator.validate(passVal);
if (!passVal.isValid()) {
StringBuilder sb = new StringBuilder();
for (IValidationError err : passVal.getErrors()) {
sb.append(((ValidationError)err).getMessage()).append(System.lineSeparator());
}
log.debug("addNewUser::weak password '{}', msg: {}", user.getPassword(), sb);
throw new ServiceException(sb.toString());
}
Object _user;
try {
User u = user.get(userDao);
GroupDao groupDao = getBean(GroupDao.class);
u.getGroupUsers().add(new GroupUser(groupDao.get(getDefaultGroup()), u));
_user = getBean(IUserManager.class).registerUser(u, user.getPassword(), null);
} catch (NoSuchAlgorithmException | OmException e) {
throw new ServiceException("Unexpected error while creating user");
}
if (_user == null) {
throw new ServiceException(UNKNOWN.getMessage());
} else if (_user instanceof String) {
throw new ServiceException((String)_user);
}
User u = (User)_user;
u.getRights().add(Right.Room);
if (Strings.isEmpty(user.getExternalId()) && Strings.isEmpty(user.getExternalType())) {
// activate the User
u.getRights().add(Right.Login);
u.getRights().add(Right.Dashboard);
} else {
u.setType(User.Type.external);
u.setExternalId(user.getExternalId());
u.setExternalType(user.getExternalType());
}
u = userDao.update(u, sd.getUserId());
return new UserDTO(u);
});
}
@WebMethod
@DELETE
@Path("/{id}")
public ServiceResult delete(@WebParam(name="sid") @QueryParam("sid") String sid, @WebParam(name="id") @PathParam("id") long id) {
return performCall(sid, User.Right.Admin, sd -> {
UserDao userDao = getUserDao();
userDao.delete(userDao.get(id), sd.getUserId());
return new ServiceResult("Deleted", Type.SUCCESS);
});
}
@DELETE
@Path("/{externaltype}/{externalid}")
public ServiceResult deleteExternal(
@WebParam(name="sid") @QueryParam("sid") String sid
, @WebParam(name="externaltype") @PathParam("externaltype") String externalType
, @WebParam(name="externalid") @PathParam("externalid") String externalId
)
{
return performCall(sid, User.Right.Admin, sd -> {
UserDao userDao = getUserDao();
User user = userDao.getExternalUser(externalId, externalType);
// Setting user deleted
userDao.delete(user, sd.getUserId());
return new ServiceResult("Deleted", Type.SUCCESS);
});
}
@WebMethod
@POST
@Path("/hash")
public ServiceResult getRoomHash(
@WebParam(name="sid") @QueryParam("sid") String sid
, @WebParam(name="user") @FormParam("user") ExternalUserDTO user
, @WebParam(name="options") @FormParam("options") RoomOptionsDTO options
)
{
return performCall(sid, User.Right.Soap, sd -> {
if (Strings.isEmpty(user.getExternalId()) || Strings.isEmpty(user.getExternalType())) {
return new ServiceResult("externalId and/or externalType are not set", Type.ERROR);
}
RemoteSessionObject remoteSessionObject = new RemoteSessionObject(
user.getLogin(), user.getFirstname(), user.getLastname()
, user.getProfilePictureUrl(), user.getEmail()
, user.getExternalId(), user.getExternalType());
log.debug(remoteSessionObject.toString());
String xmlString = remoteSessionObject.toXml();
log.debug("xmlString {}", xmlString);
String hash = getBean(SOAPLoginDao.class).addSOAPLogin(sid, options.getRoomId(),
options.isModerator(), options.isShowAudioVideoTest(), options.isAllowSameURLMultipleTimes(),
options.getRecordingId(),
options.isAllowRecording()
);
if (hash != null) {
if (options.isAllowSameURLMultipleTimes()) {
sd.setPermanent(true);
}
sd.setXml(xmlString);
sd = getSessionDao().update(sd);
return new ServiceResult(hash, Type.SUCCESS);
}
return UNKNOWN;
});
}
}
此类主要用于登录和创建哈希以直接进入会议室、录音或一般应用程序
login方法:
用于登录操作
形参:
用户 – - 具有管理员或 SOAP 权限的 Openmeetings 用户的登录名或电子邮件
pass——密码
返回值:
带有错误代码或 SID 和用户 ID 的ServiceResult
get方法:
列出系统中的所有用户!
形参:
sid – 来自 getSession 的 SID
返回值:
用户列表
add方法:
像通过前端一样添加一个新用户,但也会激活帐户来执行 SSO 查看创建哈希的方法并使用这些方法!
形参:
sid – 来自 getSession 的 SID
user– 用户对象
确认 - 无论是否发送电子邮件,留空自动发送
返回值:
添加的用户 ID 或错误代码
delete方法:
通过 id 删除某个用户
形参:
sid – 来自 getSession 的 SID
id – openmeetings 用户 ID
返回值:
删除的用户ID,否则为错误代码
deleteExternal方法:
通过外部用户 ID 删除某个用户
形参:
sid – 来自 getSession 的 SID
externalType – externalUserId
externalId – 外部用户 ID
返回值:
删除的用户 ID,或错误代码
getRoomHash方法:
说明:为某个SID设置SessionObject,设置这个Session-Object后就可以使用SID+一个RoomId进入任意一个房间。 … 如果不使用,会话哈希在创建后 15 分钟被删除。
形参:
sid – 来自 getSession 的 SID
user- 要设置的用户详细信息
options – 要设置的房间选项
返回值:
安全哈希或错误代码
小结:
此类主要是用于系统的使用者的登录以及对于有管理员权限的用户进行对其他用户的管理等操作
至此,util包下以BaseWebService包为父类派生的全部服务类便分析完成,主要功能是依赖工厂模式中的工厂Red5LoggerFactory.getLogger创建Logger对象供其他成员方法使用其error或者debug方法方便的打印调试日志以及报错日志。同时联合db.dao包下的各dao的类进行在线会议的各种操作。下周开始,着重分析Web包下的代码,web包下包含webapp文件夹,从idea可以看出是一个web项目,可能包含openmeeings的前端页面内容。