Silverlight 4에서 TCP 전송을 통해 WCF 서비스 사용

참고

Silverlight는 은퇴했으며 공식적으로 지원되지 않습니다. 자세한 내용은 Silverlight 지원 종료를 참조하세요.

이 문서에서는 Microsoft Silverlight 4에서 TCP(Transmission Control Protocol) 전송을 통해 WCF(Windows Communication Foundation) 서비스를 사용하는 방법을 설명합니다.

원래 제품 버전: Silverlight
원본 KB 번호: 2425652

요약

Silverlight 4는 이중 WCF를 구현하기 위한 새로운 선택을 제공하는 netTcp 전송 바인딩 요소를 지원합니다. 이 코드 샘플에서는 날씨 보고서 구독을 만들어 Silverlight에서 netTcp WCF를 사용하는 방법을 보여 줍니다.

WCF에 액세스하는 Silverlight를 보여 주려면 WCF 서비스 및 Silverlight WCF 클라이언트가 필요할 수 있습니다. 날씨 보고서 구독 애플리케이션을 만들려면 다음 세 단계를 수행합니다.

1단계: NetTcpBinding을 사용하여 Duplex WCF 서비스 Create

  1. 새 콘솔 프로젝트를 NetTcpWCFServiceCreate. 그런 다음 프로젝트에 새 WCF 서비스를 WeatherService 추가합니다.

  2. IWeatherService.cs 파일을 열고 다음 코드를 실행하여 서비스 계약을 정의합니다.

     namespace NetTcpWCFService
    {
        [ServiceContract(CallbackContract=typeof(IWeatherServiceCallback))]
        public interface IWeatherService
        {
            [OperationContract(IsOneWay = true)]
            void Subscribe();
                [OperationContract(IsOneWay = true)]
            void UnSubscribe();
        }
        public interface IWeatherServiceCallback
        {
            [OperationContract(IsOneWay=true)]
            void WeatherReport(string report);
        }
    }
    
  3. WeatherService.cs 파일을 열고 정적 이벤트 접근 방식을 사용하여 구독 서비스를 구현합니다. 먼저 특성을 기존 클래스에 ServiceBehavior 접두사로 지정하고 모드를 InstanceContext 서비스로 PerSession 설정해야 WeatherService 합니다. 그런 다음, 다음 코드를 실행하여 클래스의 WeatherService 기본 콘텐츠를 바꿉니다.

    [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
        public class WeatherService : IWeatherService
        {
            static event EventHandler<WeatherEventArgs> WeatherReporting;
            IWeatherServiceCallback _callback;
            public void Subscribe()
            {
                _callback = OperationContext.Current.GetCallbackChannel<IWeatherServiceCallback>();
                WeatherReporting += new EventHandler<WeatherEventArgs>(WeatherService_WeatherReporting);
            }
            public void UnSubscribe()
            {
                WeatherReporting -= new EventHandler<WeatherEventArgs>(WeatherService_WeatherReporting);
            }
            void WeatherService_WeatherReporting(object sender, WeatherEventArgs e)
            {
                // Remember check the callback channel's status before using it.
                if (((ICommunicationObject)_callback).State == CommunicationState.Opened)
                    _callback.WeatherReport(e.WeatherReport);
                else
                    UnSubscribe();
            }
        }
        class WeatherEventArgs:EventArgs
        {
            public string WeatherReport{set;get;}
        }
    
  4. 모의 날씨 보고서를 주기적으로 생성하려면 별도의 스레드를 Create. 다음 코드를 실행하여 클래스의 System.Threading 정적 생성자에 네임스페이 WeatherService 스를 추가합니다.

    static WeatherService()
    {
        ThreadPool.QueueUserWorkItem
        (
            new WaitCallback(delegate
            {
                string[] weatherArray = { "Sunny", "Windy", "Snow", "Rainy" };
                Random rand = new Random();
    
                while (true)
                {
                    Thread.Sleep(1000);
                    if (WeatherReporting != null)
                        WeatherReporting(
                            null,
                            new WeatherEventArgs
                            {
                                WeatherReport = weatherArray[rand.Next(weatherArray.Length)]
                            });
                }
            })
        );
    }
    
  5. WCF 서비스에 엔드포인트를 추가 netTcpbinding 하려면 다음 코드를 실행하여 app.config구성합니다.

     <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="NetTcpWCFService.WeatherServiceBehavior">
                    <serviceMetadata />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service behaviorConfiguration="NetTcpWCFService.WeatherServiceBehavior"
                name="NetTcpWCFService.WeatherService">
                <endpoint address="" binding="netTcpBinding" bindingConfiguration="b1"
                  contract="NetTcpWCFService.IWeatherService" />
                <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="net.tcp://localhost:4504/WeatherService" />
                    </baseAddresses>
                </host>
            </service>
        </services>
            <bindings>
                <netTcpBinding>
                    <binding name="b1">
                        <security mode="None"/>
                    </binding>
                </netTcpBinding>
            </bindings>
    </system.serviceModel>
    

    참고

    Silverlight에서 4502에서 4534까지의 일부 포트만 액세스할 수 있으며 Silverlight 액세스를 허용하려면 클라이언트 액세스 정책 파일이 필요합니다. Silverlight 액세스를 허용하는 방법에 대한 자세한 내용은 3단계를 참조하세요.

  6. Program.cs 파일을 열고 네임스페이스를 추가합니다System.ServiceModel. 다음 코드를 실행하여 메서드에서 ServiceHost 서비스를 시작합니다.Main

    static void Main(string[] args)
    {
        using (var host = new ServiceHost(typeof(WeatherService)))
        {
            host.Open();
            Console.WriteLine("Service is running...");
            Console.WriteLine("Service address: "+host.BaseAddresses[0]);
            Console.Read();
        }
    }
    

2단계: Silverlight WCF 클라이언트 Create

WCF를 사용하도록 Silverlight 애플리케이션을 Create. 서비스를 구독하거나 구독 취소하는 단추와 서비스의 날씨 보고서를 표시하는 목록 상자가 필요합니다.

  1. 새 Silverlight 프로젝트 CSSL4WCFNetTcp를 Create. 새 Silverlight 애플리케이션 대화 상자에서 새 웹 사이트에서 Silverlight 애플리케이션 호스트 확인란을 검사 Silverlight 버전을 Silverlight 4로 설정해야 합니다.

  2. 다음 코드를 실행하여 MainPage.xaml 파일을 열고 기본 Grid 요소를 편집합니다.

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="46*" />
            <RowDefinition Height="26*" />
            <RowDefinition Height="228*" />
        </Grid.RowDefinitions>
        <TextBlock Text="Silverlight NetTcp Sample" Grid.Row="0" Margin="0,0,0,10" FontSize="24"/>
        <StackPanel Orientation="Horizontal" Grid.Row="1">
            <Button Content="Subscribe weather report" Name="btnSubscribe" Click="Button_Click"/>
            <TextBlock VerticalAlignment="Center" FontStyle="Italic" Foreground="Red" Margin="5,0,0,0" Name="tbInfo"/>
        </StackPanel>
        <ListBox Name="lbWeather" Grid.Row="2" Margin="0,5,0,0"/>
    </Grid>
    
  3. WCF 서비스의 클래스에 weatherService 서비스 참조를 추가합니다. 이렇게 하려면 NetTcpWCFService 프로젝트를 시작 프로젝트로 설정하고 Ctrl+F5를 눌러 서비스를 시작합니다. 그런 다음 Silverlight 프로젝트를 마우스 오른쪽 단추로 클릭하고 서비스 참조 추가 옵션을 선택하고 서비스 참조 추가 대화 상자에서 weatherservice 주소를 입력하고 확인을 누릅니다. 그런 다음 Visual Studio 2010은 Silverlight 프로젝트에서 WCF 프록시 코드를 생성합니다.

  4. 다음 코드를 실행하여 MainPage.xaml.cs 파일을 열고 이벤트 발생 시 WCF 프록시 Loaded 를 초기화합니다.

    public partial class MainPage : UserControl,IWeatherServiceCallback
    {
        public MainPage()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(MainPage_Loaded);
        }
        bool _subscribed;
        WeatherServiceClient _client;
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            _client = new WeatherServiceClient(
                new System.ServiceModel.InstanceContext(this));
            _client.SubscribeCompleted += _client_SubscribeCompleted;
            _client.UnSubscribeCompleted += _client_UnSubscribeCompleted;
        }
        void _client_UnSubscribeCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                _subscribed = false;
                btnSubscribe.Content = "Subscribe weather report";
                tbInfo.Text = "";
            }else
                tbInfo.Text = "Unable to connect to service.";
            btnSubscribe.IsEnabled = true;
        }
        void _client_SubscribeCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                _subscribed = true;
                btnSubscribe.Content = "UnSubscribe weather report";
                tbInfo.Text = "";
            }
            else
                tbInfo.Text="Unable to connect to service.";
            btnSubscribe.IsEnabled = true;
        }
        // Display report when callback channel get called.
        public void WeatherReport(string report)
        {
            lbWeather.Items.Insert(
                0,
                new ListBoxItem
                {
                    Content = string.Format("{0} {1}",DateTime.Now, report)
                });
        }
    }
    
  5. 다음 코드를 실행하여 단추 클릭 이벤트를 처리할 이벤트 처리기를 추가합니다.

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (!_subscribed)
        {
            _client.SubscribeAsync();
        }
        else
        {
            _client.UnSubscribeAsync();
        }
        btnSubscribe.IsEnabled = false;
    }
    

3단계: 도메인 간 정책 파일 배포

  1. xml 파일 clientaccesspolicy.xmlCreate 다음 코드를 사용하여 콘텐츠를 구성합니다.

    <access-policy>
        <cross-domain-access>
            <policy>
                <allow-from>
                    <domain uri="*"/>
                </allow-from>
                <grant-to>
                    <socket-resource port="4502-4506" protocol="tcp" />
                </grant-to>
            </policy>
        </cross-domain-access>
    </access-policy>
    

    참고

    이 파일은 4502에서 4506 사이의 서버 포트에 액세스하기 위해 도메인에 있는 Silverlight 클라이언트에 권한을 부여합니다.

  2. 서버 웹 사이트의 루트 실제 디렉터리 경로(기본적으로 C:\inetpub\wwwroot IIS를 사용하는 경우)를 찾아 경로에 정책 파일을 배치합니다.