ich suche code snippets oder beispielcode für die .net c# oder vb integration über die uci schnittstelle.
gibt es hier quellen oder muß ich aus dem java reverse mir meine .net app ableiten?
ich suche code snippets oder beispielcode für die .net c# oder vb integration über die uci schnittstelle.
gibt es hier quellen oder muß ich aus dem java reverse mir meine .net app ableiten?
Hallo, wie ist denn der Zeitrahmen hierfür?
für die die alte UCI 2.x gibt es eine .NET Portierung (über .NET Remoting), aber das wird mit der neuen Version 6.0 legacy sein. Zum neuen Server 6.0 mit UCI 3.0 wird es auch einen nativen Client für Windows geben. Der Client ist in C# implementiert und reicht die UCI über eine WCF Schnittstelle nach außen weiter. Als Binding wird Named Pipes und TCP Sockets unterstützt. Damit kannst Du alle Funktionen ausführen und bekommst auch alle Events als Callback (Duplex).
Wir stehen kurz vor einer öffentlichen Preview für die Partner. Da sind dann schon viele Funktionen drin, auch wenn noch nicht alle Interfaces final sind.
Gruß Wolfgang
Wir stehen kurz vor einer öffentlichen Preview für die Partner. Da sind dann schon viele Funktionen drin, auch wenn noch nicht alle Interfaces final sind.
Gruß Wolfgang
Ich wäre auch interessiert an einem DotNet SDK.
Hallo
ich habe eine kleine Beispiel-Anwendung gebaut (siehe Anhang).
Ich habe die WCF Interfaces in dem Beispiel gegen das Release 6.0.0.7 synchronisiert. Das ist aber auch gegen 6.0.0.11 sofort lauffähig. Ansonsten muss man nur die Service Referenz gegen den laufenden Client synchronisieren.
Im Beispiel ist die Logik in der Datei "StarfaceUccClientWrapper.cs"
Zu sehen sind:
- Verbindung mit dem Client und Keep alive (das ist wichtig, damit die Verbindung nicht vom WCF wieder abgebaut wird. Die WCF-Verbindungen unterliegen einem Timeout bei Nicht-Benutzung
- Außerdem wird durch das Keep alive gewährleistet, dass die Integration auch damit klar kommt, wenn der Starface UCC Client erst später gestartet wird oder zwischendurch mal beendet wird.
- Reaktion auf Events: OnUccEvent(...). Das Interface UccServerConnectionClient ist duplex und liefert Events. Es gibt verschiedene Events, auf die gefiltert werden kann. Ein Client braucht also nicht alle denkbaren Events zu empfangen.
- Die weiteren Interface-Objekte erzeuge ich bei Bedarf: UccCallRequestsClient uccCallRequests = new UccCallRequestsClient(m_binding, m_endpointAddress);
Die Named Pipe enthält den Windows Benutzernamen. So ist gewährleistet, dass z.B. auf einem Terminal Server mehrere Clients gleichzeitig laufen können.
Der Client überprüft bei Aufrufen über die WCF Interfaces, ob der Aufruf von demselben Windows Benutzer kommt. Man kann also nicht den Client einer anderen Windows Session fernsteuern.
Es gibt die Interfaces:
Die UCI Interfaces sind teilweise durchgereicht.
Um ein neues Projekt zu starten, gehst Du so vor:
Gruß Wolfgang
Da bin ich Dir SEHR dankbar für dieses Codeschnipsel.
Mir gefällt auch der Ansatz über den Client!
Ich bedanke mich mal extremst!
Funktioniert perfekt!!!
LG
FG
Hallo Wolfgang,
bei werden neue Anrufe nicht abgefangen. Der Wrapper reagiert nur auf CallRemoved bzw. ist der uccEvent.EventType in der Funktion OnUccEvent immer UccCallRemovedEvent. Woran kann das liegen?
Gruß
Sorin
Hi Sorin,
wie schaut denn Dein Code aus?
Gruß Wolfgang
Hallo,
hab den unten verlinkten Demo Client heruntergeladen und getestet. Funktioniert soweit perfekt. Da ich normalerweise in VB.NET programmiere würde mich interessieren ob schon mal jemand die Schnittstelle in VB integriert hat.
Jetzt noch eine prinzipielle Frage. Mit dem Beispielprogramm kann ich mir wunderbar anzeigen lassen wer gerade von welchem Apparat oder über welche Gruppe auf dem aktuell am UCC Client angemeldeten Apparat anruft. Gibt es auch eine Möglichkeit sich von mehreren Apparaten anzeigen zu lassen wenn dort angerufen wird? Es geht mir um eine Anwendung, die auf einem großem Display ( in einer lauten Laborumgebung ) anzeigt wenn auf einem der Apparate der Labormitarbeiter ein Anruf eingeht, noch bevor dieser auf den Apparat im Labor weitergeleitet wird.
Bin für jeden Tipp dankbar.
Mark
Hallo,
Gibt es auch eine Möglichkeit sich von mehreren Apparaten anzeigen zu lassen wenn dort angerufen wird? Es geht mir um eine Anwendung, die auf einem großem Display ( in einer lauten Laborumgebung ) anzeigt wenn auf einem der Apparate der Labormitarbeiter ein Anruf eingeht, noch bevor dieser auf den Apparat im Labor weitergeleitet wird.
Hallo Mark,
mit der Wcf-Anbindung an den UCC Client hängst Du Dich mit auf die Session des angemeldeten Benutzers. Damit kannst Du erst mal alles sehen, was auch der Client dieses Benutzers anzeigt. Eine Möglichkeit ist, dass Du für diesen angemeldeten Benutzer für jeden der Labor-Mitarbeiter ein Besetztlampenfeld (BLF) konfigurierst. Dann siehst Du am Zustand des BLFs, ob dieser Mitarbeiter angerufen wird.
Beim "mal eben" runterschreiben, wie Du das machen könntest, ist mir leider noch ein Fehler aufgefallen. Über die WCF-Schnittstelle lassen sich die Funktionstasten überhaupt nicht abfragen, da System.Drawing.Bitmap nicht über Wfc direkt serialisierbar ist. Für die kommende Version 6.4.3.x habe ich das jetzt geändert. Die Avatare von BLFs und Calls können nun über die Wcf-Schnittstelle als Stream abgefragt werden. Mit der kommenden 6.4.3 Beta kannst Du es so machen:
Du referenzierst in Deinem Projekt die UccWrapper.dll. Dann kannst Du das Verbinden mit dem Client sehr vereinfachen und die BLFs wie folgt abfragen:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using UccWrapper;
using UccWrapper.UccServiceReference;
namespace DemoClient
{
public partial class Form1 : Form, UccServerConnectionCallback
{
private readonly UccWrapper.UccClientWatcher m_watcher = new UccClientWatcher(true);
private UccServerConnectionClient m_uccServerConnection = null;
private UccFunctionKeyRequestsClient m_uccFunctionKeyRequests = null;
private System.ServiceModel.InstanceContext m_ctx = null;
private System.ServiceModel.NetTcpBinding m_binding = null;
private readonly Dictionary<string, Panel> m_blfPanels = new Dictionary<string, Panel>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
if (m_watcher == null)
return;
if (m_watcher.IsUccClientRunning)
{
OnUccClientRunningStateChanged(true, m_watcher.TcpEndpointAddress);
}
m_watcher.UccClientRunningStateChanged += OnUccClientRunningStateChanged;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
DisconnectFromUccClient();
}
private void OnUccClientRunningStateChanged(bool isRunning, System.ServiceModel.EndpointAddress tcpEndpointAddress)
{
if (isRunning)
{
ConnectToUccClient(tcpEndpointAddress);
}
else
{
DisconnectFromUccClient();
ClearBlfs();
}
}
private void ConnectToUccClient(System.ServiceModel.EndpointAddress tcpEndpointAddress)
{
m_ctx = new InstanceContext(this);
m_binding = new NetTcpBinding
{
Security =
{
Mode = SecurityMode.Transport,
Transport = {ClientCredentialType = TcpClientCredentialType.Windows}
}
};
m_uccServerConnection = new UccServerConnectionClient(m_ctx, m_binding, tcpEndpointAddress);
m_uccFunctionKeyRequests = new UccFunctionKeyRequestsClient(m_binding, tcpEndpointAddress);
m_uccServerConnection.RegisterCallback((int) UccEventTypeFilter.UccFunctionKeyEvents);
}
private void DisconnectFromUccClient()
{
try
{
m_uccServerConnection?.UnRegisterCallback();
}
catch (Exception)
{
// ignored
}
m_uccFunctionKeyRequests = null;
m_uccServerConnection = null;
}
public void OnUccEvent(UccEventBase uccEvent)
{
BeginInvoke(new Action(() => { HandleUccEvent(uccEvent); }));
}
private void HandleUccEvent(UccEventBase uccEvent)
{
switch (uccEvent.EventType)
{
case UccEventType.UccFunctionKeysChangedEvent:
OnUccFunctionKeysChanged(uccEvent as UccFunctionKeysChangedEvent);
break;
case UccEventType.UccFunctionKeyStateEvent:
OnUccFunctionKeyStateChanged(uccEvent as UccFunctionKeyStateEvent);
break;
case UccEventType.UccGetRedirectionsForKeyAsyncEvent:
case UccEventType.UccGetCallInfoForKeyAsyncEvent:
case UccEventType.UccSearchFunctionKeyAsyncEvent:
default:
break;
}
}
private void OnUccFunctionKeysChanged(UccFunctionKeysChangedEvent uccFunctionKeysChangedEvent)
{
ClearBlfs();
if (uccFunctionKeysChangedEvent.FunctionKeys == null) return;
foreach (var uccFunctionKey in uccFunctionKeysChangedEvent.FunctionKeys)
{
if (uccFunctionKey.KeyType != UccFunctionKeyType.TypeBusyLampField) continue;
AddBlf(uccFunctionKey);
}
}
private void OnUccFunctionKeyStateChanged(UccFunctionKeyStateEvent uccFunctionKeyStateEvent)
{
UpdateBlfState(uccFunctionKeyStateEvent.FunctionKey);
}
private void ClearBlfs()
{
foreach (Control control in flowLayoutPanelBusyLampFields.Controls)
{
control.Dispose();
}
flowLayoutPanelBusyLampFields.Controls.Clear();
m_blfPanels.Clear();
}
private void AddBlf(UccFunctionKey functionKey)
{
var panel = new Panel
{
Width = 250,
Height = 50
};
var label = new Label
{
Text = functionKey.Name,
Location = new Point(50, 5)
};
panel.Controls.Add(label);
flowLayoutPanelBusyLampFields.Controls.Add(panel);
m_blfPanels[functionKey.Id] = panel;
ShowFunctionKeyState(functionKey, panel);
if (string.IsNullOrEmpty(functionKey.ImageHash)) return;
if (m_uccFunctionKeyRequests == null) return;
try
{
var img = Image.FromStream(m_uccFunctionKeyRequests.GetImageStreamForKey(functionKey.Id));
var avatarPictureBox = new PictureBox
{
Image = img,
Width = 40,
Height = 40,
Location = new Point(5, 5),
SizeMode = PictureBoxSizeMode.Zoom
};
panel.Controls.Add(avatarPictureBox);
}
catch (Exception)
{
// ignored
}
}
private void UpdateBlfState(UccFunctionKey functionKey)
{
Panel panel = null;
if (!m_blfPanels.TryGetValue(functionKey.Id, out panel)) return;
ShowFunctionKeyState(functionKey, panel);
}
private void ShowFunctionKeyState(UccFunctionKey functionKey, Panel panel)
{
switch (functionKey.State)
{
case UccFunctionKeyState.FunctionKeyStateInactive:
panel.BackColor = Color.Green;
break;
case UccFunctionKeyState.FunctionKeyStateFlashy:
panel.BackColor = Color.Yellow;
break;
case UccFunctionKeyState.FunctionKeyStateActive:
panel.BackColor = Color.Red;
break;
case UccFunctionKeyState.FunctionKeyStateQueuePause:
panel.BackColor = Color.Blue;
break;
case UccFunctionKeyState.FunctionKeyStateInvalid:
case UccFunctionKeyState.FunctionKeyStateUnavailable:
default:
panel.BackColor = Color.LightGray;
break;
}
}
}
}
Alles anzeigen
Das Ergebnis sieht dann so aus:
Mit der aktuellen 6.4.2.81 kannst Du das sinngemäß auch schreiben. Nur gibt es den Stream-Zugriff noch nicht und beim Versand von Funktionstasten-Events über die Wcf-Schnittstelle fliegt im Client eine Exception und die Wcf-Verbindung wird zerstört. Den UCC Client selbst stört das nicht, da dieser die Events anders bekommt. Mit 6.4.3.x ist es dann behoben.
Gruß Wolfgang
Mit der aktuellen 6.4.2.81 kannst Du das sinngemäß auch schreiben. Nur gibt es den Stream-Zugriff noch nicht und beim Versand von Funktionstasten-Events über die Wcf-Schnittstelle fliegt im Client eine Exception und die Wcf-Verbindung wird zerstört. Den UCC Client selbst stört das nicht, da dieser die Events anders bekommt. Mit 6.4.3.x ist es dann behoben.
Hallo Wolfgang,
danke für die schnelle Antwort. Hört sich doch schon ganz gut an.
Kann man diese 6.4.3. Version schon irgendwo runterladen?
Kannst Du den aktualisierten Code auch als komplettes C# Projekt zur Verfügung stellen? Wie schon gesagt, komme ich programmiertechnisch aus der VB Ecke und tu mir in C# deutlich leichter wenn ich auf einem lauffähigen Projekt aufbauen kann.
Danke
Mark
Hallo Mark,
ich schaue mal, dass ich Dir zeitnah eine Version und Beispielprojekt zum Testen geben kann.
Gruß Wolfgang
Hallo Wolfgang,
bin schon gespannt.
Danke
Mark
Du hast eine PN.
Gruß Wolfgang
Hallo Mark,
ich schaue mal, dass ich Dir zeitnah eine Version und Beispielprojekt zum Testen geben kann.
Gruß Wolfgang
Hallo Wolfgang,
wir werden zwar erst in zwei Tagen stolzer Besitzer einer neuen STARFACE sein, ein Beispielproject in C# würde mich aber dennoch brennend interessieren.
Mit besten Grüßen
Harald
Hallo Harald,
ich muss mal schauen, auf welchem Weg ich so was gut veröffentlichen kann (Forum, Knowledge-Base, ...).
Gruß Wolfgang
Hallo Wolfgang,
SUPER! Eine zeitnahe Umsetzung wäre genial, die Kollegen warten nämlich schon auf die Anbindung unserer Kundendatenbank. Bevor sie sich schon Workarounds angewöhnt haben möchte ich denen etwas hingestellt haben.
Besten Dank im voraus!
Harald
Anbei das diskutierte Demo-Client Projekt. Gezeigt wird die Einbindung der UccWrapper.dll und die Anbindung an den Client. Die Anwendung fragt die BLFs des Benutzers ab und stellt diese stark vereinfacht dar.
Gruß Wolfgang
Hallo,
Ich habe auf dem Rechner, auf dem der UCClient installiert ist, ds folgende probiert:
Um ein neues Projekt zu starten, gehst Du so vor:
- Visual Studio 2013
- New project, .NET Framework 4, Visual c#, Windows Forms Application
- References. Context menu "Add Service Reference…"
- Enter address: net.pipe://localhost/starface/ucclient/mex
- Press "Go"
- Select service "UccServerConnection"
- Enter a namespace, e.g. "MyUccClientReference"
- Press "OK"
Und habe folgende Fehlermeldung bekommen:
Unbekanntes URI-Präfix.
Metadaten enthalten einen Verweis, der nicht aufgelöst werden kann: "net.pipe://localhost/starface/ucclient/mex".
Es war kein an net.pipe://localhost/starface/ucclient/mex lauschender Endpunkt vorhanden, der die Nachricht annehmen konnte. Dies wird häufig durch eine fehlerhafte Adresse oder SOAP-Aktion verursacht. Weitere Details finden Sie unter "InnerException", sofern vorhanden.
Der Pipeendpunkt "net.pipe://localhost/starface/ucclient/mex" wurde nicht auf dem lokalen Computer gefunden.
Wenn der Dienst in der aktuellen Projektmappe definiert ist, sollten Sie die Projektmappe erstellen und den Dienstverweis erneut hinzufügen.
Die installierte UCC Client Version ist 6.7.1.212, OS ist Windows 10 Enterprise LTSC, Visual Studio Community 2019
IIS ist installiert, und https://docs.microsoft.com/de-…edure-for-the-wcf-samples wurde abgearbeitet.
Alle Programme und Commandlines wurde als Administrator ausgeführt.
Könnte das Problem sein, daß der Client erst installiert wurde, und dann später die IIS Umgebung?
Gruß,
Kai
Hallo Kai,
die Anleitung ist veraltet. Nimm den Weg wie es im vorherigen Beitrag in diesem Thread gezeigt wird und verwende die UccWrapper.dll.
Gruß Wolfgang
Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!