Beyond IM, Exchange Server also offers the ability to perform real-time audio and video conferencing as well as data sharing through Exchange Conferencing Server. This platform, which is an additional server that works with Exchange, adds a server component to the NetMeeting environment so you can host more users and schedule your meetings without requiring a client organizer PC and so administrators can control how much bandwidth and how many real-time meetings can take place on their network.
You can use Outlook or a Web interface for scheduling and listing your real-time conferences. The Web interface also introduces an additional object model that you can use to schedule real-time conferences from your own applications. Figure 19-4 shows this Web interface.
Beyond scheduling from the Web, users can also browse for real-time conferences from the Web. Both scheduling and browsing rely on ASP, so you can look at the source code behind the pages to learn more about how they work. Figure 19-5 shows the interface for browsing real-time conferences.
To show how to use Exchange Conferencing Server as part of an application, the Training application has the ability to schedule classes as online classes. You must have Exchange Conferencing Server somewhere in your environment to take advantage of this ability. The first step in scheduling an online class is to find the list of online classrooms that are available. Figure 19-6 shows the interface for searching Active Directory from the Training application to find real-time resources.
Exchange Conferencing Server labels its resources with a special globally unique identifier (GUID) in the msExchResourceGUID Active Directory property so that the application can find real-time resources. This GUID is {A1C12B06-B01B-11d2-85EB-00C04FA376EB} . If you perform an ADSI search using that GUID, you will find all Exchange Conferencing Server resources on your network. All Exchange Conferencing Server resources are created as users with mailboxes stored inside of Exchange so that the online conference room can generate free/busy information and you can use Outlook direct booking, which allows Outlook to schedule a conference directly in the conference room's calendar.
Once we find the online conference room we're looking for, we must check the free/busy information for that conference room. The Training application can view the free/busy information for any room or person. A real-time conference room is exactly the same as a regular mailbox, so we can just use Collaboration Data Objects (CDO) or WebDAV to query for the free/busy information for that room. The application also takes an extra step while it is querying the free/busy information to find out whether the mailbox it is querying is a conferencing mailbox or a regular mailbox. The user interface for querying for free/busy information is shown in Figure 19-7. Note that the Training application can use either server-side CDO or WebDAV to query for free/busy information. This means that free/busy lookup works whether the Exchange server is on the same machine or a different machine from the application. (For example, the Training application might be running on a Microsoft SharePoint Portal Server [SPS] 2001 server, which is discussed in the companion material posted on the book's Web site.)
Once we know that the instructor wants to schedule an online conference, we can schedule the online event in a number of ways. The most straightforward and easiest way is to just use CDO to send a meeting request to the corresponding conferencing mailbox as an attendee. An event sink sitting on the conferencing server will capture the meeting request and respond to the organizer with the URL that should be sent to all attendees. This is different from direct booking in Outlook, in which the URL is automatically placed in the appointment in each attendee 's calendar. The e-mail that is sent by the conferencing server is shown in Figure 19-8.
The code to schedule a real-time conference via CDO is shown here:
Dim oConfig As New CDO.Configuration oConfig.Fields(cdoSendEmailAddress) = "thomriz@mydomain.com" oConfig.Fields(cdoMailboxURL) = "http://myserver/exchange/thomriz" oConfig.Fields.Update 'Create new Appointment Dim oAppt As New CDO.Appointment oAppt.Configuration = oConfig oAppt.Subject = "New Virtual Meeting" oAppt.StartTime = "11/9/2003 10:00 AM" oAppt.EndTime = "11/9/2003 11:00 AM" oAppt.Attendees.Add "lylecu@mydomain.com" Dim oAttendee As CDO.Attendee Set oAttendee = oAppt.Attendees.Add("realtimeconf@mydomain.com") oAppt.Resources = "realtimeconf@mydomain.com" Dim oCalRequest As CDO.CalendarMessage Set oCalRequest = oAppt.CreateRequest oCalRequest.Message.Send
Exchange Conferencing Server includes an object that you can call to schedule real-time conferences from your applications: the XConfLoc.ConferenceLocatorManager object. This is the same object that the ASP pages from Exchange Conferencing Server use. The reason you should use this object rather than CDO to schedule and cancel your conferences is that CDO is not remotable ”your code must run directly on the server. This implies that if you have an Exchange Conferencing server that is different from the Exchange server where the conferencing mailbox is located, you have to write the code to use Distributed COM (DCOM) to create a CDO session on that remote server to cancel or schedule the conference. The Exchange Conferencing Server object does all of this for you under the covers.
The XConfLoc.ConferenceLocatorManager object is contained in the file xconfloc.exe under the Microsoft Exchange Conferencing Server directory. You can install Exchange Conferencing Server on servers that do not even have Exchange Server on them. This means that you can set up pure Exchange Conferencing servers. Be sure that you have the latest Service Pack for Exchange Conferencing Server on these servers before you attempt to use this object.
The XConfLoc.ConferenceLocatorManager object provides a number of classes. The only class I'll cover is the IScheduler class.
Note | Much of this code is modeled after the online scheduling ASP code that Exchange Conferencing Server itself uses; however, this class is undocumented, so you use this code at your own risk. The following code could stop working or could change at any point if Microsoft changes the API. |
To schedule an online resource, the IScheduler interface gives you a Send method. You pass the domain user in the form domain\user to TO recipients, the CC recipients, the SMTP address of the online conference room (the conferencing mailbox), the start date of the meeting, the end date of the meeting, a Boolean that specifies whether the meeting is recurring, the subject of the meeting, the body of the meeting request, whether the meeting is private, the password (if there is one) to join the meeting, and a variable (which is the URL to the meeting) that will be filled by the method call. Note that the start and end times must be in Universal Time Coordinate (UTC) offset format. A code example will make this easier to understand. Here is the code from the Training application to schedule a real-time course:
On Error Resume Next 'Try to create the conference locator from SP1 Set ConfLocatorManager = CreateObject("XCONFLOC.ConferenceLocatorManager") If Err.Number = 0 Then Call ConfLocatorManager.GetInterface("IID_IScheduler", Scheduler) 'Get the Auth User from the server variables strDOMAINUSER = Request.ServerVariables("LOGON_USER") set oADInfo = Server.CreateObject("ADSystemInfo") strDomainName = oADInfo.DomainShortName 'see if Logonuser has the domain name as well iRevSlash = InStr(1,strDOMAINUSER,"\") If iRevSlash = 0 Then 'Add the domain at the beginning strDOMAINUSER = strDomainName & "\" & strDOMAINUSER End If strEmail = Session("UserEmail") strConfRoomSMTP = Request.Form("confroomSMTP") 'Turn the start time and end time into UTC 'Figure out offset from UTC for this timezone dDate = Now 'Break out Date / Time dCurDate = Month(dDate) & "/" & Day(dDate) & "/" & Year(dDate) dHour = Hour(dDate) If Len(dHour) = 1 Then dHour = "0" & Hour(dDate) End If dMinute = Minute(dDate) If Len(dMinute) = 1 Then dMinute = "0" & Minute(dDate) End If dCurTime = dHour & ":" & dMinute iTimeZoneOffset = getUTCOffset(dCurDate,dCurTime) 'iTimeZoneOffset is in minutes dStartDate = CDate(Request.Form("date") & " " _ & Request.Form("starttime")) dateStartTime = DateAdd("n", iTimeZoneOffset, dStartDate) dEndDate = CDate(Request.Form("date") & " " & Request.Form("endtime")) dateEndTime = DateAdd("n", iTimeZoneOffset,dEndDate) strSubject = Cstr(Request.Form("title")) strBody = Cstr(Request.Form("description")) 'Don't make it private so other students can join in and 'see the course vbPrivate = false 'Don't support recurring meetings bIsRecurring = "" strURL = "" 'Add the instructor as a To recipient strToRecips = Session("UserEmail") 'Book the resource 'Response.Write "<P>" & strDOMAINUSER & strToRecips & strCcRecips _ & strConfRoomSMTP & dateStartTime & dateEndTime _ & bIsRecurring & strSubject & strBody & vbPrivate _ & strDecodedPassword & strURL 'Response.End Err.Clear CALL Scheduler.Send(strDOMAINUSER, strToRecips, strCcRecips, _ strConfRoomSMTP, dateStartTime, dateEndTime, _ bIsRecurring, strSubject, strBody, vbPrivate, _ strDecodedPassword, strURL) Err.Clear 'Clear all errors since conf server in beta 'throws error even if successful. If Err.Number <> 0 Then bConfSendError = True End If If strURL <> "" Then 'We got back the conference URL, store it on the item iAppt.Fields(strSchema & "httppathonlineconference").Value = strURL iAppt.Fields.Update End If <script language=javascript runat=server> function GetUTCOffset(dDate, dTime) { var s; //Take the date and figure out the UTC offset from it var dValue = dDate + " " + dTime; var d = new Date(dValue); s = d.getTimezoneOffset(); return(s); } </script>
Canceling an online conference is easy. All you do is call the Delete method on the Scheduler object. You pass in the username in the form domain\username , the SMTP of the online resource, the ID of the meeting (which can be obtained from the URL to the meeting), and whether the meeting is recurring. The following code example shows these steps:
'Try to create the conference locator from SP1 On Error Resume Next Set ConfLocatorManager = CreateObject("XCONFLOC.ConferenceLocatorManager") If Err.Number = 0 Then Call ConfLocatorManager.GetInterface("IID_IScheduler", Scheduler) 'Get the Auth User from the server variables strDOMAINUSER = Request.ServerVariables("LOGON_USER") Set oADInfo = Server.CreateObject("ADSystemInfo") strDomainName = oADInfo.DomainShortName 'see if Logonuser has the domain name as well iRevSlash = InStr(1,strDOMAINUSER,"\") If iRevSlash = 0 Then 'Add the domain at the beginning strDOMAINUSER = strDomainName & "\" & strDOMAINUSER End If 'Get SMTP Address of the resource strSMTPAddress = iAppt.Fields(strSchema & "confroomsmtp").Value 'Get the meeting ID 'Parse the online http address in reverse to id= strMeetingURL = iAppt.Fields(strSchema _ & "httppathonlineconference").Value iResult = instrrev(strMeetingURL,"?id=") txtMeetingID = Mid(strMeetingURL,iResult+4) fRecurring = False CALL Scheduler.Delete(strDOMAINUSER, strSMTPAddress, _ txtMeetingID, fRecurring) End If
The final function you will probably perform with Exchange Conferencing Server is listing all the available conferences to your users. The easiest way to do this is to use the list.asp file that comes with Exchange Conferencing Server (Service Pack 1 or later). You can place this file in an IFRAME in your Web application to list the available conferences. However, if you want to do custom work to display the available conferences, you must use GetProfilesByTime2 from the IConferenceLocator2 interface. You must pass the meeting ID (if you are looking for a particular conference), the username in the form domain\username , the start time and end time to query for (in UTC offset, not in the local time zone), and a variable that will hold a collection of conference profiles that are returned. The returned conference profiles correspond to the IConferenceProfiles interface, which you can find in the Exchange Conference Management Service 1.0 Type Library (xconfmgr.exe). The following code makes this clearer:
'Try to create the conference locator from SP1 or later On Error Resume Next Set ConfLocatorManager = CreateObject("XCONFLOC.ConferenceLocatorManager") If Err.Number = 0 Then Call ConfLocatorManager.GetInterface("IID_IConferenceLocator2", _ ConfLocator2) 'Get the Auth User from the server variables strDOMAINUSER = Request.ServerVariables("LOGON_USER") set oADInfo = Server.CreateObject("ADSystemInfo") strDomainName = oADInfo.DomainShortName 'see if Logonuser has the domain name as well iRevSlash = InStr(1, strDOMAINUSER, "\") If iRevSlash = 0 Then 'Add the domain at the beginning strDOMAINUSER = strDomainName & "\" & strDOMAINUSER End If CALL ConfLocator2.GetProfilesByTim2("", strDOMAINUSER, _ dateStart, dateEnd, confProfiles) For Each confProfile In confProfiles 'Retrieve the subject using the UserProperty method Response.Write "Name: " & confProfile.UserProperty(PR_SUBJECT, _ MAPI_RESOURCE) Response.Write "Start time: " & confProfile.StartTime Response.Write "End time: " & confProfile.EndTime Response.Write "Organizer: " & confProfile.Organizer Response.Write "Is Recurring: " & confProfile.IsRecurring Response.Write "Meeting ID: " & confProfile.MeetingID Next End If