Openmeetings4.0.0二次开发日志(三)使用webservice调用OM接口(1)

来源:互联网 发布:淘宝快递投诉怎么撤销 编辑:程序博客网 时间:2024/06/06 03:26

Openmeetings是将一些接口用webservice发布出来,可供调用的,今天讲一讲如何用利用webservice调用实现某些具体的业务场景。
首先启动Openmeetings,如果是linux上的,则切换到openmeetings的安装目录上运行nohup ./red5.sh start,windows版本下只需运行red5.bat文件即可,启动成功如下图:
这里写图片描述
然后可以访问:http://localhost:5080/openmeetings/services/services。
在这上面你可以看到所有被发布出来的接口信息,有CalendarWebService,ErrorWebService,FileWebService,GroupWebService,InfoWebService,RecordingWebService,RoomWebService,UserWebService 8个接口,其中,我们主要使用RoomWebService和UserWebService两个,一个主要用于创建房间,一个主要用于人员登录。
新建一个项目,然后使用wsimport导入webservice的接口到项目里面。代开命令行工具,输入

wsimport -s D:\workspace\app\src\main\java  -p userwebService   http://localhost:5080/openmeetings/services/UserService?wsdl

这句话的作用是将UserService生成的接口文件导入到我的项目中,wsimport是jdk自带的命令,可以根据wsdl文档生成客户端中间代码,基于生成的代码编写客户端,可以省很多麻烦。-s 表示 在指定的目录生成java源文件。-p会生成指定的包结构,最后是接口文件的路径。导入完成后的接口文件如下图:
这里写图片描述
接着,导入房间接口文件:

wsimport -s D:\workspace\app\src\main\java  -p roomService   http://localhost:5080/openmeetings/services/RoomService?wsdl

如下图:
这里写图片描述

至此,接口导入完成,可以开始使用了。
现在来看几个业务场景:

  • 现在有老师这个角色,他可以越过登录页面直接进入Openmeetings的公共房间。
  • 老师也可以创建自定义的会议房间
  • 有学生这个角色 ,学生没有自主进入公共房间或者创建房间的权限,但他可以被随意分配到一个老师创建的房间进行面试。

这三个需求的所有代码实现我先给出来,如下:

package com.avie.app.controller;import java.rmi.RemoteException;import java.util.ArrayList;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;import java.util.Set;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import roomService.OrgApacheOpenmeetingsWebserviceRoomWebService;import roomService.RoomCountDTO;import roomService.RoomDTO;import roomService.RoomWebService;import roomService.Type;import userwebService.ExternalUserDTO;import userwebService.OrgApacheOpenmeetingsWebserviceUserWebService;import userwebService.RoomOptionsDTO;import userwebService.ServiceResult;import userwebService.UserWebService;@RestController@RequestMapping(value="/op")@Api(value="测试对接openmeetings",tags="op")public class SysmenuController {    private static RoomWebService roomService;    private static UserWebService userService;    private static Map<Long, Integer> roomCountersMap = new LinkedHashMap<>();    static {        OrgApacheOpenmeetingsWebserviceRoomWebService orgRoom = new OrgApacheOpenmeetingsWebserviceRoomWebService();        OrgApacheOpenmeetingsWebserviceUserWebService orgUser = new OrgApacheOpenmeetingsWebserviceUserWebService();        userService = orgUser.getUserService();        roomService = orgRoom.getRoomWebServicePort();    }    @ApiOperation(value="老师加入公共房间")      @RequestMapping(value="/addToRoom",method=RequestMethod.POST)    public ServiceResult createRoom(String id,String fname,String lname,Long roomId) throws RemoteException{        String sid = getSid("duyu","Dy@@2017");        //创建外部人员访问信息        ExternalUserDTO user = new ExternalUserDTO();        user.setEmail("zda@dwa.com");        user.setExternalId(id);        user.setExternalType("Teacher");        user.setFirstname(fname);        user.setLastname(lname);        user.setLogin("T"+id);        RoomOptionsDTO options = new RoomOptionsDTO();        options.setRoomId(roomId);        options.setShowAudioVideoTest(true);        options.setModerator(true);        userwebService.ServiceResult serviceRs = userService.getRoomHash(sid, user, options);        System.out.println(serviceRs.getMessage());        roomCountersMap.putIfAbsent(roomId, 1);        return serviceRs;    }    @ApiOperation(value="给学生随机分配面试房间")      @RequestMapping(value="/randomToRoom",method=RequestMethod.POST)    public ServiceResult randomToRoom(String id,String fname,String lname) throws RemoteException{        ServiceResult serviceRs;        //用户登录,获取sid        String sid = getSid("root","Avie@2017");        //创建外部人员访问信息        ExternalUserDTO user = new ExternalUserDTO();        user.setEmail("zda@dwa.com");        user.setExternalId(id);        user.setExternalType("student");        user.setFirstname(fname);        user.setLastname(lname);        user.setLogin("S"+id);        //取得所有开启的房间号,然后查询每个房间号的人数,如果有房间人数为1的房间,则视为空闲房间,可以进入面试        List<Long> list = new ArrayList<Long>();        Set<Long> set = roomCountersMap.keySet();        list.addAll(set);        OrgApacheOpenmeetingsWebserviceRoomWebService orgRoom = new OrgApacheOpenmeetingsWebserviceRoomWebService();        RoomWebService roomService = orgRoom.getRoomWebServicePort();        List<RoomCountDTO> rooms = roomService.counters(sid, list);        Long roomId = (long)0;        for(RoomCountDTO room : rooms) {            if(room.getRoomCount() == 1) {                roomId = room.getRoomId();            }        }        if(roomId == 0) {            serviceRs = new ServiceResult();            serviceRs.setMessage("对不起当前没有空闲房间,请等待!");            serviceRs.setType("noRoom");            return serviceRs;        }        RoomOptionsDTO options = new RoomOptionsDTO();        options.setRoomId(roomId);        options.setShowAudioVideoTest(true);        options.setModerator(false);        serviceRs = userService.getRoomHash(sid, user, options);        System.out.println(serviceRs.getMessage());        return serviceRs;    }    @ApiOperation(value="老师创建自定义房间")      @RequestMapping(value="/customizeRoom",method=RequestMethod.POST)    public ServiceResult customizeRoom(String id,String fname,String lname,String ty,long num) throws RemoteException{        //得到service        String sid = getSid("duyu","Dy@@2017");        RoomDTO room = new RoomDTO();        room.setType(Type.fromValue(ty));        room.setCapacity(num);        room.setAllowRecording(true);        room = roomService.add(sid, room);        //创建外部人员访问信息        ExternalUserDTO user = new ExternalUserDTO();        user.setEmail("zda@dwa.com");        user.setExternalId(id);        user.setExternalType("Teacher");        user.setFirstname(fname);        user.setLastname(lname);        user.setLogin("T"+id);        RoomOptionsDTO options = new RoomOptionsDTO();        options.setRoomId(room.getId());        options.setShowAudioVideoTest(true);        options.setModerator(true);        ServiceResult serviceRs = userService.getRoomHash(sid, user, options);        System.out.println(serviceRs.getMessage());        roomCountersMap.putIfAbsent(room.getId(), 1);        return serviceRs;    }    /**     * 得到某个登录用户的sid     */    private String getSid(String name,String pwd) {             ServiceResult rs = userService.login(name, pwd);            return rs.getMessage();    }}

让我们先来看第一个需求:

  • 现在有老师这个角色,他可以越过登录页面直接进入Openmeetings的公共房间。

在第一章的时候我介绍过Openmeetings有7个公共房间,让我们先来看看如何利用webservice进入这几个公共房间。先看上面代码中的第一部分:

这里写图片描述

这里先通过静态代码块初始化两个参数:roomService和userService。通过OrgApacheOpenmeetingsWebserviceRoomWebService和OrgApacheOpenmeetingsWebserviceUserWebService各自的get方法来得到roomService和userService的实例。

接下来是老师进入公共房间的代码:

这里写图片描述

首先是得到了一个String类型的变量sid,那么这个sid是干什么的喃?,我们来看得到sid的getSid方法,如下图:

这里写图片描述

在这里,我们得到sid传入了两个参数,用户名和密码。这里先说明一下,Openmeetings的用户分为两类。一类是内部用户,这类用户需要通过openmeetings的注册页面完成之后才能使用,这类用户是必需要密码的;另一类用户为外部用户,通过调用webservice的接口创建,不需要密码,但要创建外部用户必需先使用拥有soap权限的内部用户登录。这个soap权限并非每个用户都有,一般情况下默认只有初始化Openmeetings时创建的root用户有,所以各位童鞋这里的用户名密码需要填你设置的root用户的用户名和密码。当然,你也可以通过root用户给其他内部用户分配soap权限,使得其他内部用户也可以创建外部用户。如果你的用户没有soap权限,则会抛出以下错误:

com.sun.xml.internal.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: Marshalling Error: class org.apache.openmeetings.webservice.error.ServiceException以及其任何超类对此上下文都是未知的。 Please see the server log to find more detail regarding exact cause of the failure.    at com.sun.xml.internal.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:178) ~[na:1.8.0_111]    at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:116) ~[na:1.8.0_111]    at com.sun.xml.internal.ws.client.sei.StubHandler.readResponse(StubHandler.java:238) ~[na:1.8.0_111]    at com.sun.xml.internal.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:189) ~[na:1.8.0_111]    at com.sun.xml.internal.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:276) ~[na:1.8.0_111]    at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:104) ~[na:1.8.0_111]    at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:77) ~[na:1.8.0_111]    at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:147) ~[na:1.8.0_111]    at com.sun.proxy.$Proxy116.getRoomHash(Unknown Source) ~[na:na]    at com.avie.app.controller.SysmenuController.createRoom(SysmenuController.java:64) ~[classes/:na]    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_111]    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_111]    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_111]    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_111]    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:871) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.0.30.jar:8.0.30]    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449) ~[shiro-web-1.2.3.jar:1.2.3]    at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365) ~[shiro-web-1.2.3.jar:1.2.3]    at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90) ~[shiro-core-1.2.3.jar:1.2.3]    at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83) ~[shiro-core-1.2.3.jar:1.2.3]    at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383) ~[shiro-core-1.2.3.jar:1.2.3]    at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362) ~[shiro-web-1.2.3.jar:1.2.3]    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) ~[shiro-web-1.2.3.jar:1.2.3]    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) ~[tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521) [tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096) [tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674) [tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.30.jar:8.0.30]    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.30.jar:8.0.30]    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_111]    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_111]    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.30.jar:8.0.30]    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_111]

接下来通过userService调用其登录方法,sid正是其返回的实体ServiceResult中的message参数。那么其实很多童鞋应该能猜到了,sid其实是在Openmeetings类似于token的东西,在登录时取得,以后的任何操作都需带上这个sid,否则视为没有登录,不予操作。
拿到了sid之后。再往后看,创建了一个ExternalUserDTO的类,这个类是用来存放外部人员信息的类,其中比较关键是externalId和externalType这两个参数,分别代表外部人员的id和外部人员的类型,若这两个参数与openmeetings数据库中已有外部人员的参数一致,openmeetings则会直接使用这这个账号,如果没有一致的,则会创建一个新的账号。
再往后走,创建房间信息。首先设置房间参数的id,公共房间的id为1-7。随后setShowAudioVideoTest(true)这个方法是设置是否开启摄像头测试,最后一个setModerator(true)为设置该外部用户是否为该房间的主持人。
所有参数设置完成后,调用userService.getRoomHash(sid, user, options)方法,将上面的sid,创建的用户及设置的房间参数信息传入该方法,得到的返回值为userwebService.ServiceResult这个实体bean,如下图:

这里写图片描述

可以看到,该实体bean一个message,一个type。其实我们这里主要是拿Openmeetings返回的message,这里面方的是登录的密钥,有了它我们通过http://localhost:5080/openmeetings/hash?secure=fa1f9381-bd03-42ae-9fd9-332b5f775a1b 这条链接即可实现访问公共房间,secure后面的参数其实就是我们得到的userwebService.ServiceResult中message的值。
现在完全模拟一下这个场景,我用springBoot新建了一个web项目,在这里面,输入名字和id号,选择一个房间即可进入该房间。如下图:

这里主要重在表现功能,页面做得随意了一些

这里我把用户名和密码在页面上做成可配的只是为了演示方便,生产环境中我们可以从session或者数据库拿用户名和密码,用户只需去选择房间即可。点击老师进入公共房间后,如下图:

这里写图片描述

成功以主持人身份进入到房间。
由于时间有限,后面两个需求的实现我在下篇博客中再讲解,喜欢的童鞋可以跟进以下。

阅读全文
1 0