Windows Phone 7 equivalent to NSNotificationCenter? - iphone

I'm new to WP7 and coming from iPhone development. On iPhone I'm used to use NSNotificationCenter to notify my program of something. NSNotificationCenter is build-in the framework out of the box. Is there something similar in WP7? I stumbled uppon MVVM-Light Toolkit but I'm not sure how to use it correctly.
What I want to do:
Register to an Notification-Id and do something when Notification-Id is received
Send Notification with Notification-Id and a context (object to pass to observers)
Everyone who registers to the same Notification-Id will be notified
So something like: Registering
NotificationCenter.Default.register(receiver, notification-id, delegate);
Sending:
NotificationCenter.Default.send(notification-id, context);
Example for Registering:
NotificationCenter.Default.register(this, NotifyEnum.SayHello, m => Console.WriteLine("hello world with context: " + m.Context));
Sending ...
NotificationCenter.Default.send(NotifyEnum.SayHello, "stackoverflow context");

Here is how to do with the MVVM Light Toolkit:
Registering:
Messenger.Default.Register<string>(this, NotificationId, m => Console.WriteLine("hello world with context: " + m.Context));
Sending:
Messenger.Default.Send<string>("My message", NotificationId);

Here http://www.silverlightshow.net/items/Implementing-Push-Notifications-in-Windows-Phone-7.aspx you will find a great example on how to use push notification on windows phone 7.

I'm pretty sure that you archive the same result as NSNotificationCenter by creating a singleton which holds a list of observables that implements a specific interface based on your bussiness requirements, or call a lamba, or trigger an event, for each message sent by this singleton you will interate the list of observables and checking the message id, once you find one or more, you can call the interface method, or execute the lambda expression or trigger the event defined to digest the message contents.
Something like below:
public class NotificationCenter {
public static NotificationCenter Default = new NotificationCenter();
private List<KeyValuePair<string, INotifiable>> consumers;
private NotificationCenter () {
consumers = new List<INotifiable>();
}
public void Register(string id, INotifiable consumer) {
consumers.Add(new KeyValuePair(id, consumer));
}
public void Send(String id, object data) {
foreach(KeyValuePair consumer : consumers) {
if(consumer.Key == id)
consumer.Value.Notify(data);
}
}
}
public interface INotifiable {
void Notify(object data);
}
public class ConsumerPage : PhoneApplicationPage, INotifiable {
public ConsumerPage() {
NotificationCenter.Default.Register("event", this);
}
private Notify(object data) {
//do what you want
}
}
public class OtherPage : PhoneApplicationPage {
public OtherPage() {
NotificationCenter.Default.Send("event", "Hello!");
}
}

Related

Is there any way to send or receive images, audio and video using Photon Pun2 or Photon Chat?

I am using both packages Photon Pun2 and Photon Chat in my application. But i can't find any way to send or receive images, audio, or video via private message.
Yes there is ... However, it is quite limited.
Exactly how big are the things you have to send?
Chat
In Photon Chat Message payload is limited to something between 400.000 and 500.000 bytes. I didn't test it more in detail but if your message size hits a certain limit you are immediately disconnected without a proper feadback for the reason ^^
See Photon Chat Intro
Example
public class MyChatListner : IChatClientListener
{
public event Action<byte[]> OnReceived;
private ChatClient cient;
public void Initialize()
{
client = new ChatClient(this);
client.ChatRegion = ...;
client.Connect(....);
}
// Sicne you already work with the chat you should know but anyway
// This has to be called continuously (who knows in what intervals)
public void Heartbeat()
{
client.Service();
}
public void SendData(string recipient, byte[] data)
{
client.SendPrivateMessage(recipient, data);
}
public void OnPrivateMessage(string sender, object message, string channelName)
{
OnReceived?.Invoke((byte[])message);
}
// also will have to implement the other methods from IChatClientListener ...
}
PUN2
In Pun2 I don't know if such a limit exists but it will definitely delay everything else until the file is fully received. Here you can directly send and receive byte[] via PhotonNetwork.RaiseEvent and OnEvent (via the interface IOnEventCallback)
Example
// doesn't even have to be monobehaviour necessarily
public class FileTransmitter : IOnEventCallback
{
private const byte eventID = 42;
public event Action<byte[]> OnReceived;
public void Enable()
{
PhotonNetwork.AddCallbackTarget(this);
}
public void Disable()
{
PhotonNetwork.RemoveCallbackTarget(this);
}
public void SendData(byte[] data, SendOptions sendoptions, RaiseEventOptions raiseEventOptions = null)
{
PhotonNetwork.RaiseEvent(eventID, data, raiseEventOptions, sendoptions);
}
public void OnEvent(EventData photonEvent)
{
if(photonEvent.Code != eventID) return;
var data = (byte[]) photonEvent.CustomData;
OnReceived?.Invoke(data);
}
}
Alternatively you can of course also use the RPC directly and use e.g.
public class FileTransfer : MonoBehaviourPun
{
[PunRPC]
void ChatMessage(string fileName, byte[] content)
{
// e.g.
File.WriteAllBytes(Path.Combine(Application.persistentDataPath, fileName), content);
}
public void SendFile(string fileName, byte[] content, PhotonPlayer targetPlayer)
{
photonView.RPC(nameof(ChatMessage), targetPlayer, fileName, content);
}
}
Either way personally what I did was using only one single byte[] and encoded all required information into it. Photon will do this anyway with all parameters but if you already know exactly what data you send and how to deserialize it it is way more efficient to do it yourself e.g. in a Thread/Task. Then on the receiver side I deserialized these into the individual information again.
It's possible and working just fine (even though you should watch for the limits as #derHugo said). My implementation uses RPC to send an array of bytes using Texture2D.EncodeToPNG and then decoding it on the clients upon receiving it.
To convert the byte array back into the image, you can use Texture2D.LoadImage method.
The approach is similar for sending other multimedia types, just the encoding/decoding methods are different.
PhotonStream allows you to stream any byte[] data though the network.
In theory, any data type can be converted in to byte[], and decode them on the receiver side.
Below example script is just an example with minimal setup.
reference from: https://frozenmist.com/docs/apis/fmetp-stream/pun2-example/
It's also possible to live stream video, audio and remote commands with popular third party plugins like FMETP STREAM, which has native fast encoder for capturing your Game View and Desktop View in real time, even compatible with mobile and VR devices.
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// ref: https://frozenmist.com/docs/apis/fmetp-stream/pun2-example/
public class FMStreamPUN : Photon.Pun.MonoBehaviourPun, IPunObservable {
private Queue<byte[]> appendQueueSendData = new Queue<byte[]>();
public int appendQueueSendDataCount { get { return appendQueueSendData.Count; } }
public UnityEventByteArray OnDataByteReadyEvent = new UnityEventByteArray();
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) {
if (stream.IsWriting) {
//Send the meta data of the byte[] queue length
stream.SendNext(appendQueueSendDataCount);
//Sending the queued byte[]
while(appendQueueSendDataCount > 0) {
byte[] sentData = appendQueueSendData.Dequeue();
stream.SendNext(sentData);
}
}
if (stream.IsReading) {
if (!photonView.IsMine) {
//Get the queue length
int streamCount = (int)stream.ReceiveNext();
for (int i = 0; i < streamCount; i++) {
//reading stream one by one
byte[] receivedData = (byte[])stream.ReceiveNext();
OnDataByteReadyEvent.Invoke(receivedData);
}
}
}
}
public void Action_SendData(byte[] inputData) {
//inputData(byte[]) is the encoded byte[] from your encoder
//doesn't require any stream, when there is only one player in the room
if(PhotonNetwork.CurrentRoom.PlayerCount > 1) appendQueueSendData.Enqueue(inputData);
}
}

Pushing data from one user to another in Vaadin web app

I get the fact that it might take more than 10 lines of code (hopefully not more than 50), but I was wondering if you could help me anyway.
I'm trying to update one user's UI thread at runtime, based on another user's input. I've created a basic project which implements three predefined users (jim, tom and threeskin). I'd like to send a message from jim to tom and have it appear as a new Label object in tom's UI, without threeskin ever knowing about it, even though they're all logged in. Oh, and jim shouldn't have to refresh his page. The label should just spawn on screen out of it's own accord.
To say that I'd appreciate some help would be the understatement of the decade.
public class User {
public String nume;
public User(String nume) {
super();
this.nume = nume;
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
public class Engine implements ServletContextListener {
public static ArrayList<User>userbase;
public void contextDestroyed(ServletContextEvent arg0) { }
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("This code is running at startup");
userbase =new ArrayList<User>();
userbase.add(new User("jim"));userbase.add(new User("tom"));userbase.add(new User("threeskin"));
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
public class InfigeUI extends UI {
User us3r;
#WebServlet(value = "/*", asyncSupported = true)
#VaadinServletConfiguration(productionMode = false, ui = InfigeUI.class)
public static class Servlet extends VaadinServlet {}
protected void init(VaadinRequest request) {
VerticalLayout everything=new VerticalLayout();
setContent(everything);
if (us3r==null){everything.addComponent(auth());}else{everything.addComponent(main());}
}
ComponentContainer auth(){
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
TextField userField=new TextField();
Button login = new Button("Log in");
login.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
us3r=login(userField.getValue());
if (us3r!=null){
saveValue(InfigeUI.this, us3r);
layout.removeAllComponents();
layout.addComponent(main());
}else{Notification.show("I only know jim, tom and threeskin. Which one are you?");}}
});
layout.addComponent(userField);
layout.addComponent(login);
return layout;
}
User login(String nume){
for (int i=0;i<Engine.userbase.size();i++){
if (nume.equals(Engine.userbase.get(i).nume)){return Engine.userbase.get(i);}
}
return null;
}
static void saveValue(InfigeUI ui,User value){
ui.us3r=value;
ui.getSession().setAttribute("something", value);
VaadinService.getCurrentRequest().getWrappedSession().setAttribute("something", value);
}
ComponentContainer main(){
VerticalLayout vl=new VerticalLayout();
Label label=new Label("This is the post-login screen");
String name=new String(us3r.nume);
Label eticheta=new Label(name);
TextField to=new TextField("Send to");
TextField message=new TextField("Message");
Button sendNow=new Button("Send now!");
vl.addComponent(eticheta);
vl.addComponent(label);
vl.addComponent(eticheta);
vl.addComponent(to);
vl.addComponent(message);
vl.addComponent(sendNow);
return vl ;
}
}
Basically you want three things
UI updates for a user which does no action himself, or in other words a message sent from the server to the browser. To enable this, you need to annotate the UI class using #Push. Otherwise, the update will only be shown when the user does something which causes a server visit, e.g. clicks a button
Some way of sending messages between UI instances (there is one UI instance per user). You can use some message bus implementation for this (CDI, Spring, ...) or you can make a simple on using a static field (static fields are shared between all users). See e.g. https://github.com/Artur-/SimpleChat for one way of doing it. It's also a good idea here to avoid all *.getCurrent methods as they in many cases will refer to another UI than you think (e.g. sender when you are in the receiver code), and you will do something else than you intend.
Safely update a UI when a message arrives. This is done using UI.access, also visible in the chat example.
First of all you need to enable the server push on your project help
based on Vaadin Documentation.
However, below code example will give what you want:
Create an Broadcast Listener Interface:
public interface BroadcastListener {
public void receiveBroadcast(final String message);
}
The Broadcaster Class:
public class Broadcaster {
private static final List<BroadcastListener> listeners = new CopyOnWriteArrayList<BroadcastListener>();
public static void register(BroadcastListener listener) {
listeners.add(listener);
}
public static void unregister(BroadcastListener listener) {
listeners.remove(listener);
}
public static void broadcast(final String message) {
for (BroadcastListener listener : listeners) {
listener.receiveBroadcast(message);
}
}
}
Your UI with Push Enalbed (via Annotation):
#Push
public class BroadcasterUI extends UI implements BroadcastListener {
#Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
final TextArea message = new TextArea("",
"The system is going down for maintenance in 10 minutes");
layout.addComponent(message);
final Button button = new Button("Broadcast");
layout.addComponent(button);
button.addClickListener(new Button.ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
Broadcaster.broadcast(message.getValue());
}
});
// Register broadcast listener
Broadcaster.register(this);
}
#Override
public void detach() {
Broadcaster.unregister(this);
super.detach();
}
#Override
public void receiveBroadcast(final String message) {
access(new Runnable() {
#Override
public void run() {
Notification n = new Notification("Message received",
message, Type.TRAY_NOTIFICATION);
n.show(getPage());
}
});
}
you can find the full link here.

log4net: How to distinguish between different forms on the same UI thread?

is there a way (NDC, Properties, ...?) to have a name/id per form that is included in all log4net messages, so I can distinguish between the forms in all log messages?
I have many service methods etc. that are used in all my forms, and I'd like to see e.g. that a service was called as a result of user input in what form (think multiple nonmodal similar forms (same class), running in the same UI thread, containing a button, and in the button's Click-Event, a service method is called. Inside the service method, there are logging calls. In the log messages, I'd like to have a property containing the information of in exactly which form instance the button was clicked in).
I don't want to modify ALL logging calls. The examples in the web for log contexts / NDC all only talk about multiple clients / asp.net requests / etc., not multiple forms in 1 thread.
Thanks,
Tim
To do this, set the properties in the form's Activated event to what you want to log:
private void Form1_Activated(object sender, System.EventArgs e)
{
// for example
log4net.GlobalContext.Properties["Name"] = this.GetType().Name;
log4net.GlobalContext.Properties["Id"] = this.Id;
}
The in your logging configuration, you can reference the properties in the PatternLayout for each appender:
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%property{Name} : %property{Id} : [%level]- %message%newline" />
</layout>
Edit: to preserve multiple values, use a stack, as in this unit test which outputs:
Now in TestClass1 Now in TestClass2
using log4net.Appender;
using log4net.Config;
using log4net.Core;
using log4net.Layout;
using NUnit.Framework;
namespace log4net.Tests
{
[TestFixture] // A NUnit test
public class log4net_Stacks
{
[SetUp]
public void Setup()
{
ConsoleAppender ca = new ConsoleAppender
{
Layout = new PatternLayout("%property{demo}"),
Threshold = Level.All
};
ca.ActivateOptions();
BasicConfigurator.Configure(ca);
}
[Test]
public void Stacks_Demo()
{
new TestClass1().Method1();
LogManager.GetLogger("logger").Debug("");
ThreadContext.Stacks["demo"].Clear();
}
private abstract class BaseTestClass
{
protected static void AddToStack(string message)
{
ThreadContext.Stacks["demo"].Push(message);
}
}
private class TestClass1 : BaseTestClass
{
public void Method1()
{
AddToStack("Now in " + GetType().Name);
var tc2 = new TestClass2();
tc2.Method2();
}
}
private class TestClass2 : BaseTestClass
{
public void Method2()
{
AddToStack("Now in " + GetType().Name);
}
}
}
}

Is there any counter observable through Rx?

I am looking for something I would call CounterObservable One side would count the numbers on it and other side would be the observer side that will receive notification every time total count changes.
In other words I will have something like this
public CounterObservable totalMailsReceived = new CounterObservable(0);
public void OnNewMail(Mail mail)
{
totalMailsReceived++;
///Rest of the code goes here
}
on the Observer side I will have
mailManager.totalMailsReceived.Subscribe(count => labelCount.Text = count.ToString());
Or if I want to go real classy, I would use Paul Betts' ReactiveUI like the following
mailManager.totalMailsReceived.ToProperty(x => x.TotalMailsReceived);
I have so far found nothing in Rx that could help me. But I figured if I create my own class that implements IObservable<int>. I am thinking of leveraging the Sample MSDN Code for IObservable implementation for that.
My questions are
1. Is that MSDN Sample thread-safe ?
2. Is there really nothing in Rx already that does what I am trying to do ?
Just use a BehaviorSubject:
public class MailServer
{
private BehaviorSubject<int> _count = new BehaviorSubject<int>(0);
public IObservable<int> TotalMailsReceived
{
get { return _count; }
}
public void OnNewMail(Mail mail)
{
_count.OnNext(_count.Value + 1);
}
}
Or, if you decide to go deeper into Rx, so that you are just observing a Mail stream, then you can use Scan operator which is good for that and Publish to remember the most recent value and multicast it to all subscribers.
You can write this new extension method:
public IObservable<T> RunningTotal<T>(this IObservable<T> source)
{
return source.Scan(0, sum => sum + 1);
}
And use it like so:
public class MailServer
{
private IConnectableObservable<int> _total;
private IDisposable _subscription;
public MailServer(IObservable<Mail> incomingMail)
{
_total = incomingMail.RunningTotal().Publish(0);
_subscription = _total.Connect();
}
public IObservable<int> TotalMailsReceived
{
get { return _total; }
}
}

RxJava (or Rx.NET) equivalent of ReactiveCocoa's RACObserve

Given an arbitrary field on a Java object, I want to create an Observable that will watch that field and push a new result to an Observer every time the value of the field changes. ReactiveCocoa has a macro called RACObserve, which appears to do exactly this.
I want to know how to implement similar functionality using RxJava.
For example, say I had the following simple class:
public class Foo {
enum State {
Idle,
Ready,
Error
}
private State currentState = State.Idle;
//methods that can change currentState
}
I want to create an Observable<State> that will push the new state to an Observer every time something changes the value of currentState.
In ReactiveCocoa, it looks like I would write something sort of like the following (please excuse my pseudo Objective-C):
[RACObserve(self, currentState) subscribeNext:^(NSString *newState) {
NSLog(#"%#", newState);
}];
How would I achieve similar functionality in RxJava? I'm thinking that I may need to wrap all changes to currentState in a setter, but it's not clear to me where I should then call Observable.create and how to feed the changes of currentState to an Observer.
ReactiveCocoa is actually more similar to ReactiveUI (http://www.reactiveui.net) than just plain Rx. And in ReactiveUI, you can use this.WhenAnyValue(x => x.PropName) to do exactly what you want.
I stumbled across this same problem recently, I ended up using PropertyChangeListener, which will emit an object when a property is changed, see the following:
Update Listener:
public class GameUpdateListener {
public static Observable<Object> changed(Game game) {
final BehaviorSubject<Object> subject = BehaviorSubject.create((Object)game);
game.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
subject.onNext( (Object)propertyChangeEvent.getNewValue());
}
});
return subject;
}
}
Some custom object:
public class Game {
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
...
public setSomeField(String field){
this.field = field;
pcs.firePropertyChange("field", this.field, field);
}
public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener) {
pcs.addPropertyChangeListener(propertyChangeListener);
}
...
}
Observe:
Game game = new Game();
GameUpdateListener listener = new GameUpdateListener();
final Observable<Object> gameObserver = listener.changed(game);
gameObserver.subscribe(new Action1<Object>() {
#Override
public void call(Object o) {
Log.e(TAG, "Object Changed");
}
});
game.setSomeField("New value");
This will work fine as long as you don't need to instantiate your object again. Perhaps a solution to this is to create a local setter method and emit a change there.
Since your question title contains "or Rx.NET", here is my suggestion (I dunno bout RxJava, you may find something similar).
You probably will have to leverage some sort of mechanism in the setter. The standard way in .NET is by using the INotifyPropertyChanged interface.
Then by firing the events, you can create an IObservable<T> from this stream by using
Observable.FromEvent<TEvent, TArgs>()
You can find a really good example of what you want to do (.NET) here.
(credits to Rob Foncesa-Ensor)
I think what you are after is a Subject<T>. It implements IObserver<T>, so you can call OnNext(T) to fire a new value, as well as IObservable<T>, which you can expose it as publicly so it can be subscribed to.
If you need it to fire the latest value to new subscribers, you can use a ReplaySubject<T> with a buffer size of 1.
Here's a basic implementation:
public class SomeService
{
private Subject<int> values = new Subject<int>();
public IObservable<T> Values
{
get
{
// AsObservable prevents it from being cast back to Subject
return values.AsObservable();
}
}
// Private; called by some internal mechanism
private void SetValue(int newValue)
{
newValue.OnNext(newValue);
}
}